首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >斯威夫特UISplitViewController如何从三列到双列

斯威夫特UISplitViewController如何从三列到双列
EN

Stack Overflow用户
提问于 2021-07-11 12:43:18
回答 2查看 438关注 0票数 2

我在弄清楚如何构造UISplitViewController时遇到了很多麻烦。

我要:

  • 主视图中的侧栏(总是)
  • 我希望第一个侧边栏导航项目(动物)显示三重(侧边栏,动物列表,动物细节)
  • 我希望第二个侧边栏导航项(配置文件)显示双(侧栏,配置文件视图)。

我看到其他应用程序(例如GitHub)也在这样做,但我真的不知道它们是如何管理的。资源很难找到,我所见过的大多数教程只显示了一种或另一种列样式。

我主要是在寻找如何构建这种良好架构的答案,但是任何代码都会受到极大的赞赏!

SceneDelegate

代码语言:javascript
运行
复制
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard let windowScene = (scene as? UIWindowScene) else { return }
    window = UIWindow(frame: windowScene.coordinateSpace.bounds)
    window?.windowScene = windowScene
    window?.rootViewController = ViewController(style: .tripleColumn)
    window?.makeKeyAndVisible()
}

根视图控制器

代码语言:javascript
运行
复制
class ViewController: UISplitViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        viewControllers = [
            SidebarViewController(),
            AnimalsViewController(),
            AnimalDetailViewController()
        ]
        
        // Example attempt at removing the secondary view
        setViewController(ProfileViewController(), for: .supplementary)
        setViewController(nil, for: .secondary)
        hide(.secondary)
    }
}

理想行为

动物

Profile

干杯!

EN

回答 2

Stack Overflow用户

发布于 2022-06-20 20:05:10

没有“官方”的方法去做,但这是可能的。据我所知,解决这个问题的最好方法之一是在根视图控制器中有两个UISplitViewController实例,并在需要时在它们之间进行权衡。这是我的方法(大约):

免责声明:在上一次WWDC22 on UIKit实验室期间,该代码与苹果工程师进行了协商。他们证实,非常不幸的是,他们目前没有提供一种方便的办法,而且这种做法可能是最好的办法。反馈被归档,它的ID被传递给工程师,所以希望我们能在iOS 17 :D中得到一个正式的API。

雷达://FB10140263 10140263

步骤1.初始化UISplitViewController

代码语言:javascript
运行
复制
private lazy var doubleColumnSVC: UISplitViewController = {
    $0.primaryBackgroundStyle = .sidebar
    // setup your SVC here
    $0.setViewController(doubleColumnPrimaryNC, for: .primary)
    return $0
}(UISplitViewController(style: .doubleColumn))

private lazy var tripleColumnSVC: UISplitViewController = {
    $0.primaryBackgroundStyle = .sidebar
    // setup your SVC here
    $0.setViewController(tripleColumnPrimaryNC, for: .primary)
    return $0
}(UISplitViewController(style: .tripleColumn))

步骤2.初始化您的侧栏VC和两个独立的UINavigationController

我发现它是交换边栏VC的最可靠的解决方案。对于单个UINavigationController实例,存在一个边栏不会随机出现的bug。两个实例解决了这个问题,同时仍然保持单个SidebarVC具有适当的焦点状态,并且已经部署了内容。

代码语言:javascript
运行
复制
// Sidebar is shared and swapped between two split views
private lazy var sideBar = YourSideBarViewController()
private lazy var doubleColumnPrimaryNC = UINavigationController(
    rootViewController: UIViewController()
)
private lazy var tripleColumnPrimaryNC = UINavigationController(
    rootViewController: UIViewController()
)

步骤3.创建要存储当前显示的SVC的属性

在接下来的步骤中,当两个实例之间切换时,它将派上用场。

代码语言:javascript
运行
复制
private var current: UISplitViewController?

步骤4.在需要时实现两种样式之间的切换

每当您想要导航到与侧栏不同的屏幕时,都应该调用此函数。

代码语言:javascript
运行
复制
private func toggleStyleIfNeeded(_ style: UISplitViewController.Style) {
    switch style {
    case .doubleColumn:
        // skip if the desired column style is already set up
        if current === doubleColumnSVC { return }
        // reassign current
        current = doubleColumnSVC

        // here add doubleColumnSVC as child view controller
        // here add doubleColumnSVC.view as subview

        // swap the sidebar
        doubleColumnPrimaryNC.setViewControllers([sideBar], animated: false)

        // here remove tripleColumnSVC from parent
        // here remove tripleColumnSVC.view from superview

    case .tripleColumn:
        // skip if the desired column style is already set up
        if current === tripleColumnSVC { return }
        // reassign current
        current = tripleColumnSVC

        // here add tripleColumnSVC as child view controller
        // here add tripleColumnSVC.view as subview

        // swap the sidebar
        tripleColumnPrimaryNC.setViewControllers([sideBar], animated: false)

        // here remove doubleColumnSVC from parent
        // here remove doubleColumnSVC.view from superview

    default:
        return
    }
    // If you are using UITabBarController for your compact style, assign it here
    current?.setViewController(tabBar, for: .compact)
}

在以“这里”开头的行中,您需要编写自己的代码。我已经简化了代码示例,使其更短。

步骤5.使用动态列享受您的SVC!

现在你基本上准备好了!使用根VC上的这个简单的帮助方法(或任何处理导航和管理SVCs的方法),您将拥有实现所需的所有功能,这是一个具有动态列数的UISplitViewController

代码语言:javascript
运行
复制
func setViewController(
    _ viewController: UIViewController,
    for column: UISplitViewController.Column,
    style: UISplitViewController.Style
) {
    toggleStyleIfNeeded(style)
    current?.setViewController(viewController, for: column)
}

我们在生产中使用这种方法已经有几个月了,而且效果很好。该应用程序支持iOS、iPadOS和Mac催化剂。有一些东西,比如定制状态栏样式和获得一致的侧边栏按钮,要完美地工作有点棘手,但是有了一些调整和UISplitViewControllerDelegate的帮助,一切都是可能的。

祝好运!

如果有人曾经走过这条路,并且能够分享建议,请这样做!我想了解更多关于如何提高用户和开发人员的动态拆分视图体验的知识。

票数 2
EN

Stack Overflow用户

发布于 2022-06-19 12:06:54

要从3列切换到2列,您必须使用两列(UISplitViewController(style: .doubleColumn)重新初始化UISplitViewController(style: .doubleColumn并将其重新分配到window.rootViewController

在重新初始化UISplitViewController时,可以分配现有的视图控制器对象来维护当前状态,也可以初始化新的状态。如果您分配了现有的视图控制器对象,那么在第一次创建这些对象之后,将它们存储在变量中可能是很方便的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68336349

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档