您可以使用UITabBarControllerDelegate 来完成。
选项1:创建UITabBarController的子类
class MyTabBar: UITabBarController, UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
}
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
if let currentlySelectedViewController = self.viewControllers?[self.selectedIndex] as? YourThirdTabViewController,
let presentedViewController = currentlySelectedViewController.presentedViewController {
presentedViewController.dismiss(animated: false, completion: nil)
}
return true
}
}
在这里,我假设我有自己的 UITabBarController 子类,它在视图 didLoad 中使用 self.delegate = self 设置为 UITabBarControllerDelegate。
选项 2: 在他们的 ViewDidLoad 中制作 TabBarController 的 ViewController UITabBarControllerDelegate
如果您不想拥有自己的UITabBarController 子类,您只需在每个ViewController 的ViewDidLoad 中将自己设置为UITabBarControllerDelegate
如果您决定走不继承UITabBarController 的路径,您可以对UIViewController 使用通用协议或扩展并确认UITabBarControllerDelegate 以避免代码重复
protocol TabBarControllerProtocol: UITabBarControllerDelegate where Self: UIViewController {}
extension TabBarControllerProtocol {
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
if let currentlySelectedViewController = self.tabBarController?.viewControllers?[self.tabBarController?.selectedIndex ?? 0] as? SomeViewController,
let presentedViewController = currentlySelectedViewController.presentedViewController {
presentedViewController.dismiss(animated: false, completion: nil)
}
return true
}
}
在任何一个 ViewController 中,你都可以这样说
class SomeViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.tabBarController?.delegate = self
}
}
extension SomeViewController: TabBarControllerProtocol {}
就是这样。
shouldSelect viewController 会在每次用户点击选项卡进行切换时被调用。
if 条件检查 selectedIndex 处的 ViewController 是否(已选择而不是新的)是否是特定感兴趣的 viewController 并检查此视图控制器是否已呈现任何内容,如果已呈现,它将调用dismiss on它
这样,当用户将标签从第三个标签切换到任何其他标签时,如果第三个标签 VC 以模态方式呈现了另一个视图控制器,它将在切换标签之前将其关闭。