【问题标题】:Split view on iPad portrait mode results in a useless view being presented on startupiPad 纵向模式下的拆分视图会导致启动时显示无用的视图
【发布时间】:2021-12-11 09:29:33
【问题描述】:

使用以下代码,Useless View 在 iPad 纵向模式下的应用启动时显示。一按后退按钮会导致详细视图显示“链接 1 目标”。只有在第二次按下时才会显示侧边栏。这不是我们想要的几乎所有应用程序的行为。

如果我们从代码中删除无用视图,我们会在启动时看到一个空白屏幕,我们仍然必须按一次后退按钮才能到达链接 1 目标,两次才能到达侧边栏。此外,侧边栏中的列表样式似乎不太理想。

我们想要的行为是在应用启动时显示链接 1 目标,然后单击“后退”按钮将我们带到侧边栏。这是我们所期望的任何应用程序甚至可能使用 SwiftUI 3 的完全标准行为吗?

struct ContentView: View {
    @State var selection: Int? = 0
    var body: some View {
        NavigationView {
            List {
                NavigationLink("Link 1", tag: 0, selection: $selection) {
                    Text("Link 1 destination")
                }
                NavigationLink("Link 2", tag: 1, selection: $selection) {
                    Text("Link 2 destination")
                }
            }
            
            //If we delete the Useless View, we still have to press Back twice
            //to get to the sidebar nav.
            Text("Useless View")
                .padding()
        }
    }
}

【问题讨论】:

  • 是的,它是设计的。如果您不需要它,请使用堆栈导航视图样式,例如 stackoverflow.com/a/62624598/12299030
  • @Asperi 我要去双列。问题是它不能正常工作。应删除“无用视图”,因为选择了其中一个导航链接。看看 Apple Music 或许多其他应用程序如何在 iPad 上纵向运行。如果应用程序已停止并且您输入它,则按一次导航返回按钮以查看选择当前窗格的侧边栏。 SwiftUI 无法做到这一点。
  • This blog post 可能会有所帮助。
  • @Yrb 哇!感谢您花时间回复,它解决了问题!如果您将其发布为答案,我会接受。
  • @Asperi 关键是 SwiftUI 无法支持开箱即用的非常简单的案例,您必须对 UIKit 基础进行神秘的修补,如本案例所示,才能让事情正常工作。我发现这在 SwiftUI 中很常见。

标签: swiftui swiftui-navigationview


【解决方案1】:

@Yrb 评论 pointed 到正确的轨道,修改底层 UIKit UISplitViewController 以强制显示主列。然而,在细节视图中有些重的视图,在速度较慢的 iPad 上出现和消失的主列有一些闪烁。所以我用Introspect library

struct ContentView: View {
    @State var selection: Int? = 0
   
    var body: some View {
        NavigationView {
            List {
                NavigationLink("Link 1", tag: 0, selection: $selection) {
                    Text("Link 1 destination")
                }
                NavigationLink("Link 2", tag: 1, selection: $selection) {
                    Text("Link 2 destination")
                }
            }
            //In my case I never have a 'Nothing Selected' view, you could replace EmptyView() here
            //with a real view if needed.
            EmptyView()
        }
        .introspectSplitViewController { svc in
            if isPortrait { //If it's done in landscape, the primary will be incorrectly disappeared
                svc.show(.primary)
                svc.hide(.primary)
            }
        }
    }
}

这符合我们的预期,没有闪烁或其他伪影。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多