iPad上的SwiftUI导航-如何显示主列表

时间:2019-09-11 11:22:17

标签: swift swiftui

我的应用程序具有简单的导航需求

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

我具有此设置并且可以在iPhone上运行,但是当我在iPad上以纵向模式运行该应用程序时,主列表始终处于隐藏状态。

我在从第一个列表到第二个列表的导航链接上使用.isDetailLink(false),因此两个列表始终位于主列中。在iPad横向模式中,所有功能均按预期工作,但在纵向模式中,详细信息视图将填充屏幕。我可以从屏幕左侧轻扫以显示列表,但我想向用户提供更多的清晰度。

我想显示或添加后退按钮以显示主/列表侧(类似于Apple Notes应用)。在iPhone上,默认情况下会显示“后退”按钮,但在纵向模式下的iPad上,它什么都没有。

这就是我在iPhone上看到的 enter image description here

但这就是我在iPad上看到的 enter image description here

父母名单

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())。有趣的是,这需要像常规修饰符一样位于导航视图的外部,而不是在导航标题的内部。

5 个答案:

答案 0 :(得分:7)

在纵向模式下,默认的拆分视图不起作用。将来可能会修复此问题,但当前的选项似乎是:
(a)将第一个列表的导航视图样式更改为.navigationViewStyle(StackNavigationViewStyle(),以便导航将像在iPhone上那样工作,并推送每个视图。

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

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

答案 1 :(得分:4)

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

通过将.padding()添加到NavigationView中,似乎可以实现始终显示母版的行为。

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

虽然不确定是否打算这样做。将来可能会中断(使用Xcode 11.0,可在iOS 13.0上的模拟器和具有13.1.2的设备上使用)。

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

答案 2 :(得分: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")
        }
    }
}

具有以下结果: An iPad with a button at the top left saying "Pick Item" An iPad screenshot with a navigation column on the left side. The column has a header with the text "Pick Item"

答案 3 :(得分:0)

看看这个解决方案here

希望能帮到你

答案 4 :(得分:0)

对于我的项目,我正在使用此扩展程序。 对于 iPhone、iPad,如果您提供 forceStackedStyle: true,它们将始终使用 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()
        }
    }
}