【问题标题】:iOS Black screen when close modally presented view controller关闭模态呈现的视图控制器时iOS黑屏
【发布时间】:2021-02-17 12:13:19
【问题描述】:

我有一个标签栏控制器,假设用户转到第三个标签并在第三个视图控制器中,用户按下一个按钮,我将视图控制器呈现为模态。

现在如果用户切换选项卡让我们说选项卡 1 或 2 而不关闭模态呈现的视图控制器,并且意味着当他回到选项卡 3 时,用户仍然可以看到模态呈现的视图控制器,现在如果用户关闭这里是模态呈现的视图控制器,然后是黑屏而不是打开模态呈现的视图控制器的视图控制器。

可能的解决方法是我隐藏标签栏控制器,以便用户必须先关闭模态显示的视图控制器。但这不是现在的要求。由于某些原因,我无法隐藏底部标签栏控制器。

请建议我如何进行以下操作

  1. 首先,当用户在打开模态呈现的视图控制器后切换选项卡时,因此当他关闭模态呈现的 vc 时,他必须看到后面的屏幕
  2. 如果第 1 点是不可能的,那么当用户再次返回选项卡 3(他在其中开始模态呈现 VC)时,不应该模态呈现视图控制器。换句话说,当用户切换选项卡并打开模态呈现的视图控制器时,它必须关闭,然后才能移动到其他选项卡。

【问题讨论】:

    标签: ios swift xcode


    【解决方案1】:

    您可以使用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 子类,您只需在每个ViewControllerViewDidLoad 中将自己设置为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 以模态方式呈现了另一个视图控制器,它将在切换标签之前将其关闭。

    【讨论】:

    • 不,现在我只需要在一个视图控制器中进行此更改。所以你想让自己成为 UITabBarControllerDelegate 的想法可以工作。所以现在要问一个小问题,如何使我的视图控制器成为 UITabBarControllerDelegate。
    • @a-s-ali:我已经更新了我的答案,请检查选项 2
    • 感谢您的精彩回答
    • 是的,是的,让我试试解决方案
    • 老兄,你能告诉我如何在更改选项卡时检查模态呈现的视图控制器是否可见/附加
    猜你喜欢
    • 1970-01-01
    • 2010-12-04
    • 1970-01-01
    • 1970-01-01
    • 2016-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多