我想单击一个按钮,然后像present modally在UIKit中
一样呈现一个新视图
我已经看过“ 如何使用图纸呈现新视图 ”,但是我不想将其作为模式图纸附加到主视图。
而且我不想使用NavigationLink,因为我不希望新视图和旧视图具有导航关系。
谢谢你的帮助...
Moj*_*ini 49
你只需要一个sheet能够自我解除的简单:
struct ModalView: View {
@Binding var presentedAsModal: Bool
var body: some View {
Button("dismiss") { self.presentedAsModal = false }
}
}
Run Code Online (Sandbox Code Playgroud)
并将其呈现为:
struct ContentView: View {
@State var presentingModal = false
var body: some View {
Button("Present") { self.presentingModal = true }
.sheet(isPresented: $presentingModal) { ModalView(presentedAsModal: self.$presentingModal) }
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,我将 传递presentingModal给模态,因此您可以从模态本身中消除它,但您可以摆脱它。
fullscreen(不仅仅是视觉上)您需要访问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 }
}
}
Run Code Online (Sandbox Code Playgroud)
那么你应该使用实现这个扩展:
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)
}
}
Run Code Online (Sandbox Code Playgroud)
你可以让它fullscreen像:
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)
// }
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
struct ContentView: View {
@State private var isPresented = false
var body: some View {
Button("Show Modal with full screen") {
self.isPresented.toggle()
}
.fullScreenCover(isPresented: $isPresented, content: FullScreenModalView.init)
}
}
Run Code Online (Sandbox Code Playgroud)
struct FullScreenModalView: View {
@Environment(\.presentationMode) var presentationMode
var body: some View {
VStack {
Text("This is a modal view")
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.red)
.edgesIgnoringSafeArea(.all)
.onTapGesture {
presentationMode.wrappedValue.dismiss()
}
}
}
Run Code Online (Sandbox Code Playgroud)
希望这个回答能帮到大家!在下面评论你的结果。
参考:此链接
| 归档时间: |
|
| 查看次数: |
97 次 |
| 最近记录: |