SwiftUI模态视图

3gtaxfhh  于 2023-05-16  发布在  Swift
关注(0)|答案(1)|浏览(104)

从任何类或结构中模态显示SwiftUI视图的最佳方式是什么?我使用UIKit中的UIHostingController。有没有更好的方法可以只使用SwiftUI?
ContentView,带有用于显示SwiftUI视图的按钮

struct ContentView: View {
    var body: some View {
        Button {
            //  Present the view
            presentView(controller: UIHostingController(rootView: view))
        } label: {
            Text("Present view")
        }
    }
    
    var view: some View {
        Button {
            //  Dismiss the view
            dismissView()
        } label: {
            Rectangle()
                .overlay(
                    Text("Dismiss view")
                )
        }
    }
}

用于呈现SwiftUI视图的函数

extension ContentView {
    //  Returns the top view controller
    func topViewController() -> UIViewController? {
        let keyWindow = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
        if var topController = keyWindow?.rootViewController {
            while let presentedViewController = topController.presentedViewController { topController = presentedViewController }
            return topController
        } else { return nil }
    }
    
    //  Presents the SwiftUI view in a UIHostingController
    func presentView(controller: UIViewController) {
        controller.view.backgroundColor = .none
        controller.modalPresentationStyle = .overCurrentContext
        topViewController()?.present(controller, animated: false, completion: nil)
    }
    
    //  Removes the UIHostingViewController from root view
    func dismissView() {
        topViewController()?.dismiss(animated: false, completion: nil)
    }
}
xwbd5t1u

xwbd5t1u1#

你可以像这样展示模态表单:

struct ContentView: View {
   @State private var showSheet = false

   var body: some View {
       Button("Present") { 
           showSheet.toggle() 
       }.font(.largeTitle)
       .sheet(isPresented: $showSheet) { 
           SheetView() 
       }
    }
}

struct SheetView: View {
   @Environment(\.dismiss) var dismiss

    var body: some View {
        ZStack {
           Button { 
              dismiss() 
           } label: {
               Image(systemName: "xmark.circle")
                 .font(.largeTitle)
                 .foregroundColor(.gray)
           }
         }
         .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topTrailing)
         .padding()
    }
}

或者像这样在全屏上呈现模态:

struct ContentView: View {
   @State private var showSheet = false

   var body: some View {
       Button("Present") { 
          showSheet.toggle() 
       }.font(.largeTitle)
        .fullScreenCover(isPresented: $showSheet) {
              SheetView()
       }
   }
}
   
struct SheetView: View {
    @Environment(\.presentationMode) var presentationMode
 
     var body: some View {
    
         ZStack {
            Button { 
               presentationMode.wrappedValue.dismiss() 
             } label: {
                Image(systemName: "xmark.circle")
                .font(.largeTitle)
                .foregroundColor(.gray)
             }
       }
        .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topTrailing) 
        .padding()
   }
}

对于你的评论,这是没有问题的,你可以这样做:

struct ContentView: View {
    @State private var showSheet = false

    var body: some View {
        ZStack {
            Button("Present") {
                showSheet.toggle()
            }
            .font(.largeTitle)
        
            if showSheet {
                ZStack {
                    Button {
                        showSheet.toggle()
                    } label: {
                        Image(systemName: "xmark.circle")
                            .font(.largeTitle)
                            .foregroundColor(.gray)
                    }
                    .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topTrailing)
                    .padding()
                }
                .background(.ultraThickMaterial)
            }
        }
    }
}

相关问题