【问题标题】:How to run the split view on iPad using SwiftUI?如何使用 SwiftUI 在 iPad 上运行拆分视图?
【发布时间】:2020-12-12 14:27:39
【问题描述】:

似乎有一种简单的方法可以让好看的 iOS 应用在 iPad 空间上运行。不涉及重写 SwiftUI 应用程序。

基本的SplitViewSplitViewController 问题似乎......就像一个考虑不周的问题空间......我有一个基本的 - 带有 ContentView 的显示卡 - 我希望它在 iPad 上运行...只是一个更大的视口...

有什么简单的方法可以使用 SwiftUI 实现这一点?

【问题讨论】:

标签: ios ipad swiftui


【解决方案1】:

这就是你如何按照Apple Fruta app 示例设置你的 iPhone、iPad 和 mac 应用程序,使用 Xcode12,iOS14 和 macOS11 作为最低目标。

使用这种实现 SwiftUI 的方式,您将拥有 iPad 和 mac 使用的拆分视图。关于 iPhone,您将拥有经典的标签栏。

这是一个可以使用的代码,所以如果你不需要mac应用程序,只需删除#else#end之间的部分即可。我实现了它以防其他人觉得它很方便,因为它非常适合多平台应用程序项目。 #if os(iOS)#else 之间的代码适用于 iPhone 和 iPad。

查找我在代码中添加的 cmets,这些 cmets 解释了创建拆分视图的时间点。

根据设备保存导航类型的 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 布局时遇到了一个“错误”......我有超过 5 个选项,并且当前的 iOS 13 似乎在 6 个项目后中断了......找到了一些 Cocoapods 来处理 TabBar - 但他们遇到了 GeometryReader 崩溃的问题......如果这不是一件事 - 这是你的母亲...... :^) 所以我m 目前在 pickel 中 - 回到白板...
  • 我目前没有在应用程序中使用导航视图 - 我想我已经在欢迎页面上使用按钮构建了自己的导航 - 好吧也许这很愚蠢 - 但现在我尝试了 TabBarNavigation 和它完全超过了 6 个项目......我第一次尝试使用 NavigationView 导致无限嵌套的导航栏......我得到了一些有用的东西......所以现在我正在考虑合并一些适用于上面 iPad 代码的东西。我真的不想要 iPad 边栏...我想要(不知道该区域的名称...页面)显示我的卡片图像的页面并且没有边栏...
猜你喜欢
  • 2020-01-27
  • 1970-01-01
  • 2022-01-25
  • 2020-05-17
  • 1970-01-01
  • 1970-01-01
  • 2014-01-24
  • 2023-04-03
  • 1970-01-01
相关资源
最近更新 更多