Para mostrar un modal (estilo iOS 13)
Solo necesita un simple sheet
con la capacidad de despedirse a sí mismo:
struct ModalView: View {
@Binding var presentedAsModal: Bool
var body: some View {
Button("dismiss") { self.presentedAsModal = false }
}
}
Y presentarlo como:
struct ContentView: View {
@State var presentingModal = false
var body: some View {
Button("Present") { self.presentingModal = true }
.sheet(isPresented: $presentingModal) { ModalView(presentedAsModal: self.$presentingModal) }
}
}
Tenga en cuenta que pasé el presentingModal
al modal para que pueda descartarlo del modal en sí, pero puede deshacerse de él.
Para hacerlo REALMENTE presente fullscreen
(no solo visualmente)
Necesita acceder a la ViewController
. Entonces necesita algunos contenedores auxiliares y cosas del entorno:
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 }
}
}
Entonces deberías usar implementar esta extensión:
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)
)
self.present(toPresent, animated: true, completion: nil)
}
}
Finalmente
puedes hacerlo fullscreen
así:
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
}
}
}
}
UIKit
. ¿Tienes alguna razón especial?