gpt4 book ai didi

ios - UINavigationController inside UITabBarController inside UISplitViewController(仍然)以模态方式显示细节 Controller 而不是推送

转载 作者:可可西里 更新时间:2023-11-01 01:07:21 30 4
gpt4 key购买 nike

在我的通用应用程序中,我有一个似乎非常常见的设置,具有根 UISplitViewController,使用 UITabBarController 作为 masterViewController ,然后我想:

  • 如果我使用的是垂直 iPhone,则将详细 View Controller 插入堆栈
  • 在横向 iPhone 6+ 和其他更大的屏幕(如 iPad 等)上的 UISplitViewController 的 detailViewController 中显示细节 Controller

为此,我的设置与所有提到类似问题的讨论中描述的设置完全相同:

但这些问题中提到的解决方案均无效。其中一些创建无限递归循环和 EXC_BAD_ACCESS。我尝试的最新方法只是简单地以模态方式呈现细节 View Controller ,而不是将其推送到 iPhone 上的堆栈中。我所做的是创建一个自定义的 UISplitViewController 子类:

    class RootSplitViewController: UISplitViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
}
}

extension RootSplitViewController: UISplitViewControllerDelegate {
func splitViewController(_ splitViewController: UISplitViewController, showDetail vc: UIViewController, sender: Any?) -> Bool {
if let tabController = splitViewController.viewControllers[0] as? UITabBarController {
if(splitViewController.traitCollection.horizontalSizeClass == .compact) {
tabController.selectedViewController?.show(vc, sender: sender)
} else {
splitViewController.viewControllers = [tabController, vc]
}
}

return true
}

func splitViewController(_ splitViewController: UISplitViewController, separateSecondaryFrom primaryViewController: UIViewController) -> UIViewController? {
if let tabController = splitViewController.viewControllers[0] as? UITabBarController {
if let navController = tabController.selectedViewController as? UINavigationController {
return navController.popViewController(animated: false)
} else {
return nil
}
} else {
return nil
}
}
}

下面是主视图 Controller 中显示详细 View Controller 的代码:

self.performSegue(withIdentifier: "showReference", sender: ["tags": tags, "reference": reference])

从 Firebase 加载的 tagsreference 在哪里。当然,“showReference”转场属于“显示详细信息(例如替换)”类型。

第一个委托(delegate)方法被正确调用,当我在 UITabBarController 中单击列表中的项目时,断点就证明了这一点。然而细节 View Controller 仍然以模态方式呈现在 iPhone 上。不过在 iPad 上没问题:细节 View Controller 出现在右侧,正如预期的那样。

上面提到的大多数答案都非常陈旧,一些解决方案是在 Objective-C 中实现的,所以可能我在转换中做错了什么,或者从那时起 UISplitViewController 实现中发生了一些变化。

有人有什么建议吗?

最佳答案

我想通了。事实上,它与我试图展示的目标 View Controller 有关。在 UISplitViewControllerDelegate 中我覆盖的 2 个方法中,只有第一个被调用:

func splitViewController(_ splitViewController: UISplitViewController, showDetail vc: UIViewController, sender: Any?) -> Bool {
if let tabController = splitViewController.viewControllers[0] as? UITabBarController {
if(splitViewController.traitCollection.horizontalSizeClass == .compact) {
tabController.selectedViewController?.show(vc, sender: sender)
} else {
splitViewController.viewControllers = [tabController, vc]
}
}

return true
}

但我在测试的第一个分支中显示的 View Controller 已经嵌入到 UINavigationController 中,所以我实际上是在将 UINavigationController 显示到另一个中,并且在那种情况下,模式更有意义。所以在这种情况下,我需要显示 UINavigationController 的顶 View Controller ,我认为这是我在委托(delegate)中重写的第二个方法的目的,但它从未被调用过。所以我通过以下实现就在那里做到了:

extension RootSplitViewController: UISplitViewControllerDelegate {
func splitViewController(_ splitViewController: UISplitViewController, showDetail vc: UIViewController, sender: Any?) -> Bool {
if let tabController = splitViewController.viewControllers[0] as? UITabBarController {
if(splitViewController.traitCollection.horizontalSizeClass == .compact) {
if let navController = vc as? UINavigationController, let actualVc = navController.topViewController {
tabController.selectedViewController?.show(actualVc, sender: sender)
navController.popViewController(animated: false)
} else {
tabController.selectedViewController?.show(vc, sender: sender)
}
} else {
splitViewController.viewControllers = [tabController, vc]
}
}

return true
}
}

这似乎在 iPhone 和 iPad 上都能完美运行

关于ios - UINavigationController inside UITabBarController inside UISplitViewController(仍然)以模态方式显示细节 Controller 而不是推送,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55758146/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com