ios - 在 SwiftUI 中呈现新 View

标签 ios swiftui

我想单击一个按钮,然后呈现一个新 View ,例如 UIKit 中的以模态方式呈现 enter image description here

我已经看到“How to present a new view using sheets ”,但我不想将其作为模式表附加到主视图。

而且我不想使用NavigationLink,因为我不希望新 View 和旧 View 有导航关系。

感谢您的帮助...

最佳答案

显示模态框(iOS 13 风格)

您只需要一个简单的sheet,并且能够自行关闭:

struct ModalView: View {
    @Binding var presentedAsModal: Bool
    var body: some View {
        Button("dismiss") { self.presentedAsModal = false }
    }
}

并呈现如下:

struct ContentView: View {
    @State var presentingModal = false
    
    var body: some View {
        Button("Present") { self.presentingModal = true }
        .sheet(isPresented: $presentingModal) { ModalView(presentedAsModal: self.$presentingModal) }
    }
}

请注意我将 presentingModal 传递给了模式,这样您就可以从模式本身中将其关闭,但您也可以摆脱它。

<小时/>

使其真正呈现全屏(不仅仅是视觉上)

您需要访问ViewController。所以你需要一些辅助容器和环境东西:

struct ViewControllerHolder {
    weak var value: UIViewController?
}

struct ViewControllerKey: EnvironmentKey {
    static var defaultValue: ViewControllerHolder {
        return ViewControllerHolder(value: UIApplication.shared.windows.first?.rootViewController)

    }
}

extension EnvironmentValues {
    var viewController: UIViewController? {
        get { return self[ViewControllerKey.self].value }
        set { self[ViewControllerKey.self].value = newValue }
    }
}

那么你应该使用实现这个扩展:

extension UIViewController {
    func present<Content: View>(style: UIModalPresentationStyle = .automatic, @ViewBuilder builder: () -> Content) {
        let toPresent = UIHostingController(rootView: AnyView(EmptyView()))
        toPresent.modalPresentationStyle = style
        toPresent.rootView = AnyView(
            builder()
                .environment(\.viewController, toPresent)
        )
        NotificationCenter.default.addObserver(forName: Notification.Name(rawValue: "dismissModal"), object: nil, queue: nil) { [weak toPresent] _ in
            toPresent?.dismiss(animated: true, completion: nil)
        }
        self.present(toPresent, animated: true, completion: nil)
    }
}

终于

您可以将其设为全屏,例如:

struct ContentView: View {
    @Environment(\.viewController) private var viewControllerHolder: UIViewController?
    
    var body: some View {
        Button("Login") {
            self.viewControllerHolder?.present(style: .fullScreen) {
                Text("Main") // Or any other view you like
// uncomment and add the below button for dismissing the modal
            // Button("Cancel") {
            //       NotificationCenter.default.post(name: Notification.Name(rawValue: "dismissModal"), object: nil)
            //        }
            }
        }
    }
}

关于ios - 在 SwiftUI 中呈现新 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58958858/

相关文章:

ios - AVAssetWriter 写入黑屏视频

objective-c - UITextfield 不可编辑字段

SwiftUI CoreData 崩溃预览

ios - 这个关闭会导致内存泄漏吗?

ios - RxAlamofire 取消网络请求

swift - 无法理解 Xcode Swift 文件和结构类声明

ios - Swift 属性只有在存在 didSet 时才能正确设置(可以为空)

swiftui - 如何在 SwiftUI 中设置按钮焦点?

ios - NavigationLink 似乎只占用一点空间

ios - 使用 tableview 折叠时调整 tableview 大小