如何在 SwiftUI 中以 iPad 和纵向模式显示侧边栏

How to show in SwiftUI the sidebar in iPad and portrait mode

我在 iPad 中有一个主细节应用程序,当 运行 应用程序处于纵向模式时,边栏被隐藏。我需要按“后退”按钮才能打开边栏。

谁能帮我默认显示侧边栏? 我找到了一个建议在应用程序纵向时使用 StackNavigationViewStyle 的答案,但随后该应用程序看起来像一个巨大的 iPhone 并且消失了主 class 像侧边栏一样看起来像视图。

那是我的代码。

struct ContentView: View {
    var body: some View {
        NavigationView {
            MyMasterView()
            DetailsView()
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct MyMasterView: View {

    var people = ["Option 1", "Option 2", "Option 3"]

    var body: some View {

        List {
            ForEach(people, id: \.self) { person in
                NavigationLink(destination: DetailsView()) {
                    Text(person)
                }
            }
        }

    }
}

struct DetailsView: View {

    var body: some View {
        Text("Hello world")
            .font(.largeTitle)
    }
}

谢谢

可以做到,但目前需要通过 UIViewRepresentable 访问 UIKit 的 UISplitViewController。这是一个示例,基于 here.

中描述的解决方案
import SwiftUI
import UIKit

struct UIKitShowSidebar: UIViewRepresentable {
  let showSidebar: Bool
  
  func makeUIView(context: Context) -> some UIView {
    let uiView = UIView()
    if self.showSidebar {
      DispatchQueue.main.async { [weak uiView] in
        uiView?.next(of: UISplitViewController.self)?
          .show(.primary)
      }
    } else {
      DispatchQueue.main.async { [weak uiView] in
        uiView?.next(of: UISplitViewController.self)?
          .show(.secondary)
      }
    }
    return uiView
  }
  
  func updateUIView(_ uiView: UIViewType, context: Context) {
    DispatchQueue.main.async { [weak uiView] in
      uiView?.next(
        of: UISplitViewController.self)?
        .show(showSidebar ? .primary : .secondary)
    }
  }
}

extension UIResponder {
  func next<T>(of type: T.Type) -> T? {
    guard let nextValue = self.next else {
      return nil
    }
    guard let result = nextValue as? T else {
      return nextValue.next(of: type.self)
    }
    return result
  }
}


struct ContentView: View {
  var body: some View {
    NavigationView {
      List {
        NavigationLink("Primary view (a.k.a. Sidebar)", destination: DetailView())
      }
      NothingView()
    }
  }
}

struct DetailView: View {
  var body: some View {
    Text("Secondary view (a.k.a Detail)")
  }
}

struct NothingView: View {
  @State var showSidebar: Bool = false
  var body: some View {
    Text("Nothing to see")
    if UIDevice.current.userInterfaceIdiom == .pad {
      UIKitShowSidebar(showSidebar: showSidebar)
        .frame(width: 0,height: 0)
        .onAppear {
            showSidebar = true
        }
        .onDisappear {
            showSidebar = false
        }
    }
  }
}