我想单击一个按钮,然后呈现一个新 View ,例如 UIKit 中的以模态方式呈现
我已经看到“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/