Как инкапсулировать navigation cotroller в tab bar controller? (Программно)
Имеется стартовый tab bar
import UIKit
class StartTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
generateTabBar()
}
private func generateTabBar() {
viewControllers = [
generateVC(viewController: FirstViewController(), title: "first tab"),
generateVC(viewController: SecondViewController(), title: "second tab"),
generateVC(viewController: ThirdViewController(), title: "third tab")
]
}
private func generateVC(viewController: UIViewController, title: String) -> UIViewController {
viewController.tabBarItem.title = title
return viewController
}
}
FirstViewController выглядит следующим образом (с ним проблем нет, все работает как нужно):
import UIKit
class FirstViewController: UIViewController {
let button = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
setupViews()
setupConstraints()
}
func setupViews() {
button.setTitle("Button", for: .normal)
button.setTitleColor(.systemBlue, for: .normal)
button.titleLabel?.font = .systemFont(ofSize: 30)
button.addAction(
UIAction(
handler: { [weak self] _ in
let alert = self?.createAlert() ?? UIAlertController()
self?.present(
alert,
animated: true,
completion: nil
)
}),
for: .touchUpInside
)
view.addSubview(button)
}
private func setupConstraints() {
button.translatesAutoresizingMaskIntoConstraints = false
button.centerXAnchor.constraint(
equalTo: view.centerXAnchor).isActive = true
button.centerYAnchor.constraint(
equalTo: view.centerYAnchor).isActive = true
}
private func createAlert() -> UIAlertController {
let alert = UIAlertController(
title: "This is the last screen",
message: "Please, go back",
preferredStyle: .alert)
alert.addAction(UIAlertAction(
title: "Okey",
style: .default,
handler: nil
))
return alert
}
}
А вот c SecondViewController имеется проблема. При нажатии на кнопку, не создается стек из вью
import UIKit
class SecondViewController: FirstViewController {
override func setupViews() {
button.setTitle("Button", for: .normal)
button.setTitleColor(.systemBlue, for: .normal)
button.titleLabel?.font = .systemFont(ofSize: 30)
button.addAction(
UIAction(
handler: { [weak self] _ in
self?.navigationController?.pushViewController(SecondViewController(), animated: true)
}),
for: .touchUpInside
)
view.addSubview(button)
}
}
Как это все исправить, не меняя SceneDelegate ???
guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(windowScene: windowScene)
window?.makeKeyAndVisible()
window?.rootViewController = StartTabBarController()
По совету GPT попробовал сделать так, но не вышло(
import UIKit
class SecondViewController: FirstViewController {
override func setupViews() {
super.setupViews()
button.removeTarget(nil, action: nil, for: .allEvents)
button.addAction(
UIAction(
handler: { [weak self] _ in
let thirdVC = ThirdViewController()
self?.navigationController?.pushViewController(thirdVC, animated: true)
}),
for: .touchUpInside
)
}
}
Источник: Stack Overflow на русском