【问题标题】:SwiftUI: In SplitView, how can I detect if the master view is visible?SwiftUI:在 SplitView 中,如何检测主视图是否可见?
【发布时间】:2022-11-23 07:30:19
【问题描述】:

当 SwiftUI 创建一个 SplitView 时,它会添加一个工具栏按钮来隐藏/显示主视图。我怎样才能检测到这种变化,以便我可以调整详细信息屏幕中的字体大小并优化使用所有空间?

我试过将 .onChange 与几何一起使用,但似乎无法正常工作。

【问题讨论】:

    标签: swiftui master-detail splitview


    【解决方案1】:

    在思考了一段时间之后,我得到了这个解决方案:

    struct ContentView: View {
    @State var isOpen = true
    
    var body: some View {
        NavigationView {
            VStack{
                Text("Primary")
                    .onUIKitAppear {
                        isOpen.toggle()
                    }
                    .onAppear{
                    print("hello")
                        isOpen.toggle()
                    }
                    .onDisappear{
                        isOpen.toggle()
                        print("hello: bye")
                    }
           .navigationTitle("options")
            }
            Text("Secondary").font(isOpen ? .body : .title)
    
        }.navigationViewStyle(.columns)
    }
    
    
    }
    

    onUIKitAppear 是苹果建议的自定义extension,只有在视图呈现给用户https://developer.apple.com/forums/thread/655338?page=2后才执行

      struct UIKitAppear: UIViewControllerRepresentable {
         let action: () -> Void
         
         func makeUIViewController(context: Context) -> UIAppearViewController {
            let vc = UIAppearViewController()
            vc.delegate = context.coordinator
            return vc
         }
         
         func makeCoordinator() -> Coordinator {
            Coordinator(action: self.action)
         }
         
         func updateUIViewController(_ controller: UIAppearViewController, context: Context) {}
         
         class Coordinator: ActionRepresentable {
            var action: () -> Void
            init(action: @escaping () -> Void) {
                  self.action = action
            }
            func remoteAction() {
                  action()
            }
         }
      }
    
      protocol ActionRepresentable: AnyObject {
         func remoteAction()
      }
    
      class UIAppearViewController: UIViewController {
         weak var delegate: ActionRepresentable?
         var savedView: UIView?
         
         override func viewDidLoad() {
            self.savedView = UILabel()
            
            if let _view = self.savedView {
                  view.addSubview(_view)
            }
         }
         
         override func viewDidAppear(_ animated: Bool) {
            delegate?.remoteAction()
         }
         
         override func viewDidDisappear(_ animated: Bool) {
            view.removeFromSuperview()
            savedView?.removeFromSuperview()
         }
      }
    
      public extension View {
         
         func onUIKitAppear(_ perform: @escaping () -> Void) -> some View {
            self.background(UIKitAppear(action: perform))
         }
      }
    

    【讨论】:

      【解决方案2】:

      如果您使用的是 iOS 16,则可以使用 NavigationSplitViewNavigationSplitViewVisibility

      例子:

      struct MySplitView: View {
          @State private var columnVisibility: NavigationSplitViewVisibility = .all
          
          var bothAreShown: Bool { columnVisibility != .detailOnly }
              
          var body: some View {
              NavigationSplitView(columnVisibility: $columnVisibility) {
                  Text("Master Column")
              } detail: {
                  Text("Detail Column")
                  Text(bothAreShown ? "Both are shown" : "Just detail shown")
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-06-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多