如何在iPad上使用SwiftUI运行分屏视图?

5
似乎有一种简单的方法可以让外观良好的iOS应用程序在iPad上运行,而不需要重写SwiftUI应用程序。
基本的`SplitView`和`SplitViewController`问题似乎……看起来像是一个没有经过深思熟虑的问题空间……我已经拥有了一个基本的-使用ContentView显示卡片-我想让它在iPad上运行……只是一个更大的视口……
是否有一种使用SwiftUI轻松实现此目标的方法?

1
如何创建一个最小化、可复现的示例 - Asperi
下载以下苹果项目 https://developer.apple.com/documentation/app_clips/fruta_building_a_feature-rich_app_with_swiftui 并查找 iPhone、iPad 和 Mac 应用程序之间导航是如何定义的。你会找到你要的答案。 - Roland Lariotte
我不太明白你@RolandLariotte的意思,我看到链接是关于苹果Fruta应用程序的。但是你可以查一下导航定义方式...能否告诉我更多信息...例如要搜索的文件名或其他内容... - David
1个回答

11
这是使用Xcode12为iOS14和macOS11设置iPhone、iPad和mac应用程序的Apple Fruta app示例。使用此SwiftUI实现,您将拥有iPad和mac使用的分割视图。关于iPhone,您将获得经典的选项卡栏。这是一个可直接使用的代码,如果您不需要mac应用程序,请删除#else#end之间的部分。我实现它是因为其他人可能会觉得它很方便,因为它非常适合多平台应用项目。位于#if os(iOS)#else之间的代码适用于iPhone和iPad。请查看我在代码中添加的注释,解释了何时创建分割视图。ContentView包含根据设备类型进行导航的内容。
struct ContentView: View {

  #if os(iOS)
  @Environment(\.horizontalSizeClass) private var horizontalSizeClass
  #endif

  @ViewBuilder
  var body: some View {
    #if os(iOS)
    if horizontalSizeClass == .compact {
      TabBarNavigationView() // For iPhone
    }
    else {
      SidebarNavigationView() // For iPad
    }
    #else
    SidebarNavigationView() // For mac
      .frame(minWidth: 900, maxWidth: .infinity, minHeight: 500, maxHeight: .infinity)
    #endif
  }
}

然后,使用枚举声明经典的 iPhone 标签栏,包含你的标签 (HomeView 可以替换为任何 SwiftUI 视图):

enum TabItem {
  case home
}

struct TabBarNavigationView: View {

  @State private var selection: TabItem = .home

  var body: some View {
    TabView(selection: $selection) {

      NavigationView {
        HomeView() // Create a SwiftUI HomeView or add your view
      }
      .tabItem {
        Image(systemName: "house")
          .font(.headline)
          .imageScale(.medium) }
      .tag(TabItem.home)
    }
  }
}

这是用于容纳iPad和mac经典分屏视图的视图。当iPad处于竖屏模式时,您的视图将作为导航,而在横屏模式下添加时,则会分屏。

struct SidebarNavigationView: View {

  @SceneStorage("selection")
  var selection: String?

  var content: some View {
    List(selection: $selection) {
      NavigationLink(destination: HomeView()) {
        Label(title: { Text("Home") },
              icon: { Image(systemName: "house")
                .font(.headline)
                .imageScale(.medium) })
      }
      .tag(NavigationItem.home)
    }
    .listStyle(SidebarListStyle())
  }

  var body: some View {
    NavigationView {
      #if os(iOS)
      content
      #else
      content
        .frame(minWidth: 200, idealWidth: 200, maxWidth: 200, maxHeight: .infinity)
        .toolbar {
          ToolbarItem(placement: .navigation) {
            Button(action: toggleSidebar ) {
              Image(systemName: "sidebar.left")
                .foregroundColor(.blue)
            }
          }
        }
      #endif

      // This is the part where the magic happens for the split view.
      // Instead of the Text, add any view you want in place.
      // Play here to see what fits best for you.
      Text("Content List")
        .frame(maxWidth: .infinity, maxHeight: .infinity)

      #if os(iOS)
      Text("Split view for iPad")
        .frame(maxWidth: .infinity, maxHeight: .infinity)
      #else
      Text("Split view for macOS")
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .toolbar { Spacer() }
      #endif
    }
  }
}

extension SidebarNavigationView {
  /// Show or hide the sidebar list in macOS.
  ///
  /// Needed for when the sidebar is hidden from the user   
  /// action as there is a bug in this version of SwiftUI
  /// that block the user to show the sidebar again without
  /// this hack.
  func toggleSidebar() {
    #if os(macOS)
    NSApp
      .keyWindow?
      .firstResponder?
      .tryToPerform(#selector(NSSplitViewController.toggleSidebar(_:)),
                    with: nil)
    #endif
  }
}

谢谢Roland - 我尝试了这段代码,看起来好像可以工作 - 但是当我转换为TabBar布局时遇到了一个“bug”... 我有超过5个选项,而当前的iOS 13似乎在第6个项目后会出问题... 找到一些Cocoapods来处理TabBar - 但它们存在GeometryReader崩溃的问题... 如果不是一件事情,就是另一件... :^)所以我现在陷入了困境 - 回到白板... - David
我目前在应用程序中没有使用导航视图 - 我猜我已经用欢迎页上的按钮构建了自己的导航 - 好吧,也许这很愚蠢 - 但是现在我尝试了TabBarNavigation,超过6个项目完全崩溃了...我的第一次尝试使用NavigationView导致无限嵌套的Nav Bars......我转而使用了一些可行的方法...所以现在我正在考虑将一些可行的东西与iPad代码合并。我真的不想要一个iPad侧边栏......我想要(不知道这个区域的名字...页面)显示我的卡片图片而没有侧边栏... - David

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接