TabBarController:总是跳转到根 NavigationController
TabBarController: always jump to root NavigationController
我的应用程序中有以下层次结构:
- 有个
TabBarController
(X)
- 它的每一项都指向一个
NavigationController
(A, B, C...)
- 每个
NavigationController
s 都开始一个 TableViewController
s 的层次结构(例如 A1、A2、A3...)
现在,当用户位于 A3 时,他们可以按另一个 TabBar
项目并跳转到另一个层次结构(例如,B 层)。但是,当他们按下 A 的项目时,他们将跳回到 A3。
我确实希望他们跳转到 A1,这实际上是 A 层次结构中的“父级”UIView
。同样,如果他们按 B,他们应该跳到 B1,而不是他们在 B 层次结构中的任何地方。我不是想强迫用户返回例如A1 手动隐藏底栏(来自 TabBarController
的栏)。
实现此目标的最佳方法是什么?
可视化:
/- A - A1 - A2 - A3
X ---- B - B1 - ...
\- C - ...
以编程方式,我目前为 X (TabBarController, TabBarControllerDelegate
) 和 TableViewController
s A1,...,B1,... 自定义了 类。当用户按下一个项目时,我可以通过调试看到 segue 的目标 VC 是 A/B/... 而不是 A1/B1/... 所以我无法控制这样处理。
编辑:检查下面的故事板图像。
我不确定我是否理解正确,但底线是每当用户点击选项卡栏时,您希望用户能够看到每个 UINavigationController
的根控制器,正确吗?
您提到您已经有一个自定义 TabBarController
那么您是否尝试过 shouldSelect
方法?:
class CustomTabBarController: UITabBarController, UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
}
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
(viewController as? UINavigationController)?.popToRootViewController(animated: true)
return true
}
}
当我在操场上尝试时,这似乎有效。
这是我试过的完整代码:
import PlaygroundSupport
import UIKit
class A: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.title = "A"
let label = UILabel(frame: CGRect(origin: .init(x: 100, y: 100), size: .init(width: 200, height: 100)))
label.text = "A"
self.view.addSubview(label)
let button = UIButton(frame: CGRect(origin: .init(x: 100, y: 200), size: .init(width: 200, height: 100)))
button.setTitle("Button", for: .normal)
button.addTarget(self, action: #selector(pressed), for: .touchUpInside)
button.backgroundColor = .black
self.view.addSubview(button)
}
@objc func pressed(_ sender: UIButton) {
let a1 = A1()
self.navigationController?.pushViewController(a1, animated: true)
}
}
class A1: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let label = UILabel(frame: CGRect(origin: .init(x: 100, y: 100), size: .init(width: 200, height: 100)))
label.text = "A1"
self.view.addSubview(label)
}
}
class B: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.title = "B"
let label = UILabel(frame: CGRect(origin: .init(x: 100, y: 100), size: .init(width: 200, height: 100)))
label.text = "B"
self.view.addSubview(label)
let button = UIButton(frame: CGRect(origin: .init(x: 100, y: 200), size: .init(width: 200, height: 100)))
button.setTitle("Button", for: .normal)
button.addTarget(self, action: #selector(pressed), for: .touchUpInside)
button.backgroundColor = .black
self.view.addSubview(button)
}
@objc func pressed(_ sender: UIButton) {
let b1 = B1()
self.navigationController?.pushViewController(b1, animated: true)
}
}
class B1: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let label = UILabel(frame: CGRect(origin: .init(x: 100, y: 100), size: .init(width: 200, height: 100)))
label.text = "B1"
self.view.addSubview(label)
}
}
class CustomTabBarController: UITabBarController, UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
}
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
(viewController as? UINavigationController)?.popToRootViewController(animated: true)
return true
}
}
let nav1 = UINavigationController(rootViewController: A())
let nav2 = UINavigationController(rootViewController: B())
let tabbarVC = CustomTabBarController()
tabbarVC.view.frame = CGRect(origin: .zero, size: CGSize(width: 500, height: 500))
tabbarVC.addChild(nav1)
tabbarVC.addChild(nav2)
PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = tabbarVC
我的应用程序中有以下层次结构:
- 有个
TabBarController
(X) - 它的每一项都指向一个
NavigationController
(A, B, C...) - 每个
NavigationController
s 都开始一个TableViewController
s 的层次结构(例如 A1、A2、A3...)
现在,当用户位于 A3 时,他们可以按另一个 TabBar
项目并跳转到另一个层次结构(例如,B 层)。但是,当他们按下 A 的项目时,他们将跳回到 A3。
我确实希望他们跳转到 A1,这实际上是 A 层次结构中的“父级”UIView
。同样,如果他们按 B,他们应该跳到 B1,而不是他们在 B 层次结构中的任何地方。我不是想强迫用户返回例如A1 手动隐藏底栏(来自 TabBarController
的栏)。
实现此目标的最佳方法是什么?
可视化:
/- A - A1 - A2 - A3
X ---- B - B1 - ...
\- C - ...
以编程方式,我目前为 X (TabBarController, TabBarControllerDelegate
) 和 TableViewController
s A1,...,B1,... 自定义了 类。当用户按下一个项目时,我可以通过调试看到 segue 的目标 VC 是 A/B/... 而不是 A1/B1/... 所以我无法控制这样处理。
编辑:检查下面的故事板图像。
我不确定我是否理解正确,但底线是每当用户点击选项卡栏时,您希望用户能够看到每个 UINavigationController
的根控制器,正确吗?
您提到您已经有一个自定义 TabBarController
那么您是否尝试过 shouldSelect
方法?:
class CustomTabBarController: UITabBarController, UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
}
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
(viewController as? UINavigationController)?.popToRootViewController(animated: true)
return true
}
}
当我在操场上尝试时,这似乎有效。
这是我试过的完整代码:
import PlaygroundSupport
import UIKit
class A: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.title = "A"
let label = UILabel(frame: CGRect(origin: .init(x: 100, y: 100), size: .init(width: 200, height: 100)))
label.text = "A"
self.view.addSubview(label)
let button = UIButton(frame: CGRect(origin: .init(x: 100, y: 200), size: .init(width: 200, height: 100)))
button.setTitle("Button", for: .normal)
button.addTarget(self, action: #selector(pressed), for: .touchUpInside)
button.backgroundColor = .black
self.view.addSubview(button)
}
@objc func pressed(_ sender: UIButton) {
let a1 = A1()
self.navigationController?.pushViewController(a1, animated: true)
}
}
class A1: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let label = UILabel(frame: CGRect(origin: .init(x: 100, y: 100), size: .init(width: 200, height: 100)))
label.text = "A1"
self.view.addSubview(label)
}
}
class B: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.title = "B"
let label = UILabel(frame: CGRect(origin: .init(x: 100, y: 100), size: .init(width: 200, height: 100)))
label.text = "B"
self.view.addSubview(label)
let button = UIButton(frame: CGRect(origin: .init(x: 100, y: 200), size: .init(width: 200, height: 100)))
button.setTitle("Button", for: .normal)
button.addTarget(self, action: #selector(pressed), for: .touchUpInside)
button.backgroundColor = .black
self.view.addSubview(button)
}
@objc func pressed(_ sender: UIButton) {
let b1 = B1()
self.navigationController?.pushViewController(b1, animated: true)
}
}
class B1: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let label = UILabel(frame: CGRect(origin: .init(x: 100, y: 100), size: .init(width: 200, height: 100)))
label.text = "B1"
self.view.addSubview(label)
}
}
class CustomTabBarController: UITabBarController, UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
}
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
(viewController as? UINavigationController)?.popToRootViewController(animated: true)
return true
}
}
let nav1 = UINavigationController(rootViewController: A())
let nav2 = UINavigationController(rootViewController: B())
let tabbarVC = CustomTabBarController()
tabbarVC.view.frame = CGRect(origin: .zero, size: CGSize(width: 500, height: 500))
tabbarVC.addChild(nav1)
tabbarVC.addChild(nav2)
PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = tabbarVC