【问题标题】:How to show in SwiftUI the sidebar in iPad and portrait mode如何在 SwiftUI 中以 iPad 和纵向模式显示侧边栏
【发布时间】:2021-10-18 18:37:20
【问题描述】:

我在 iPad 上有一个主从应用程序,当以纵向模式运行应用程序时,侧边栏是隐藏的。我需要按返回按钮才能打开侧边栏。

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

这是我的代码。

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)
    }
}

谢谢

【问题讨论】:

  • 嗨,您已经找到解决方案了吗?有没有办法在 SwiftUI 中实现这一点,还是我们需要使用 UISplitViewController 来代替?
  • 我还没有找到任何解决方案。我认为这是不可能的,因为所有应用程序都以这种方式工作,甚至是邮件应用程序。

标签: ios xcode swiftui master-detail


【解决方案1】:

可以做到,但目前需要通过 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
        }
    }
  }
}

【讨论】:

    猜你喜欢
    • 2021-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多