【问题标题】:SwiftUI Navigation on iPad - How to show master listiPad 上的 SwiftUI 导航 - 如何显示主列表
【发布时间】:2020-01-13 05:29:31
【问题描述】:

我的应用有简单的导航需求

  • 列表视图(父对象)
  • 列表视图(子对象)
  • 详细视图(子对象)

我有这个设置并且在 iPhone 上工作,但是当我在 iPad 上以纵向模式运行应用程序时,主列表总是隐藏的。

我在从第一个列表到第二个列表的导航链接上使用.isDetailLink(false),因此两个列表始终保留在主列中。在 iPad 横向中,一切都按预期工作,但在纵向中,详细视图会填满屏幕。我可以从屏幕左侧滑入以显示列表,但我想为用户提供更清晰的信息。

我想显示或添加后退按钮以显示主/列表端(有点像 Apple Notes 应用程序)。在 iPhone 上,我默认获得返回按钮,但在纵向模式下的 iPad 上,它的位置没有任何内容。

这是我在 iPhone 上看到的

但这就是我在 iPad 上看到的

家长名单

struct ParentList: View {

    let firstList = ["Sample data 01", "Sample data 02", "Sample data 03", "Sample data 04", "Sample data 05"]

    var body: some View {
        NavigationView {
            List{
                ForEach(firstList, id: \.self) { item in
                    NavigationLink(destination: ChildList()){

                        Text(item)
                    }
                    .isDetailLink(false)

                }
            }
        }
    }
}

子列表

struct ChildList: View {

    let secondList = ["More Sample data 01", "More Sample data 02", "More Sample data 03", "More Sample data 04", "More Sample data 05"]

    var body: some View {
        List{
            ForEach(secondList, id: \.self) { item in
                NavigationLink(destination: ChildDetail()){

                    Text(item)

                }
            }
        }
    }
}

儿童详情

struct ChildDetail: View {

    var body: some View {
        Text("Child detail view")
    }

}

更新:截至 2019 年 10 月 17 日,我还没有找到让它工作的方法。我决定暂时使用.navigationViewStyle(StackNavigationViewStyle())。有趣的是,这需要像普通修饰符一样位于导航视图的外部,而不是导航标题的内部。

【问题讨论】:

  • 我不知道答案,但我在 iPad 上也有同样的行为。基本上,一个 List 在 iPad 上会自动变成一个 SplitView,而在纵向上它似乎隐藏了主视图。我现在没有任何帮助,但也许如果您深入研究可以为列表设置的属性,您可能会找到答案。搜索诸如“iPad”、“master”之类的东西并仔细研究 cmets。祝你好运!

标签: swift swiftui


【解决方案1】:

在纵向中,默认的拆分视图不起作用。这可能会在未来得到解决,但目前的选项似乎是:
(a) 将您的第一个列表的导航视图样式更改为.navigationViewStyle(StackNavigationViewStyle()),以便导航将像在 iPhone 上一样工作并推送每个视图。

(b) 保留默认样式,只支持 iPad 的横向

(c) 实现一个 UIKit 拆分视图控制器

【讨论】:

    【解决方案2】:

    还有一个非常老套的解决方法(参见https://stackoverflow.com/a/57215664/3187762

    通过向 NavigationView 添加 .padding() 似乎可以实现始终显示 Master 的行为。

    NavigationView {
            MyMasterView()
            DetailsView()
     }.navigationViewStyle(DoubleColumnNavigationViewStyle())
      .padding()
    

    不确定是否是有意的。将来可能会中断(使用 Xcode 11.0,在 iOS 13.0 的模拟器和 13.1.2 的设备中工作)。

    你不应该依赖它。这条评论似乎是更好的答案:https://stackoverflow.com/a/57919024/3187762

    【讨论】:

      【解决方案3】:

      在 iOS 13.4 中,“返回主视图”按钮已添加到 iPad 布局中。来自发行说明:

      当使用具有多列的 NavigationView 时,导航栏现在会显示一个用于切换列的控件。 (49074511)

      例如:

      struct MyNavView: View {
          var body: some View {
              NavigationView {
                  NavigationLink(
                      destination: Text("navigated"), 
                      label: {Text("Go somwhere")}
                  )
                  .navigationBarTitle("Pick Item")
              }
          }
      }
      

      有以下结果:

      【讨论】:

      • 这到底是什么意思?我正在尝试做一个 iPhone/iPad 应用程序和 iPad,我的应用程序在 iPad 上真的真的很不稳定。我有多个列,并且应用程序在 iPad 上的各种变体之间打开,拆分视图,横向,纵向,它在列中执行的“悬停”视图......我正在发生各种奇怪的事情,我什至可以在两个地方显示同一列 - 并排!我确定是我,但是要追查这一切是很困难的。不过很有趣!
      • @Poltavets 不只是你。 SwiftUI 似乎完成了大约 60%。但是,是的,这很有趣。 :)
      • @Tres - 很高兴知道!希望 WWDC2020 会带来一些好的改进。我真的很喜欢 SwiftUI。 WWDC2020 肯定会解决很多问题。
      【解决方案4】:

      看看这个解决方案here

      希望对你有帮助

      【讨论】:

        【解决方案5】:

        对于我的项目,我正在使用此扩展程序。 如果您提供forceStackedStyle: true,他们将始终在 iPhone、iPad 垂直方向使用 StackNavigationViewStyle。 否则将使用 DoubleColumnNavigationViewStyle

        
        var body: some View {
          NavigationView {
            Text("Hello world")
          }
          .resolveNavigationViewStyle(forceStackedStyle: false)
        }
        
        extension View {
            func resolveNavigationViewStyle(forceStackedStyle: Bool) -> some View {
                
                if forceStackedStyle || UIDevice.current.userInterfaceIdiom == .phone {
                    return self.navigationViewStyle(StackNavigationViewStyle())
                        .eraseToAnyView()
                } else {
                    return GeometryReader { p in
                        if p.size.height > p.size.width { self.navigationViewStyle(StackNavigationViewStyle())
                        } else {
                            self.navigationViewStyle(DoubleColumnNavigationViewStyle())
                        }
                    }
                    .eraseToAnyView()
                }
            }
        }
        

        【讨论】:

        • “某些视图”类型的值没有成员“eraseToAnyView”??任何帮助表示赞赏
        猜你喜欢
        • 1970-01-01
        • 2012-03-10
        • 2013-09-14
        • 1970-01-01
        • 1970-01-01
        • 2020-11-06
        • 1970-01-01
        • 2023-01-28
        • 1970-01-01
        相关资源
        最近更新 更多