web-dev-qa-db-fra.com

SwiftUI: effacer l'état modal ou réinitialiser

J'ai un modal SwiftUI dont je voudrais effacer l'état ou réinitialiser. La revitalisation serait préférable compte tenu du fait que ce modal peut ouvrir d'autres modaux qui peuvent avoir un certain état.

Voici un exemple simple:

import SwiftUI

struct OtherView: View {
    @State var otherViewState: String = ""

    var body: some View {
        TextField($otherViewState, placeholder: Text("Demo Text Input"))
    }
}

struct Demo: View {
    @State var showModal: Bool = false

    var modal: Modal {
        Modal(OtherView(), onDismiss: { self.showModal = false })
    }

    var body: some View {
        Button(action: { self.showModal = true }) {
            Text("Toggle Modal")
        }
        .presentation(self.showModal ? self.modal : nil)
    }
}

Indépendamment de la façon dont OtherView est rejeté, je voudrais le rouvrir avec son état de texte effacé, avec la condition que OtherView puisse ouvrir les modaux lui-même. L'ajout d'une méthode clear sur la structure OtherView elle-même est toujours une option, mais je ne la trouve pas maintenable.

Voici une vidéo du problème simplifié: Demo

10
michaelgmcd

Mise à jour du 11 septembre: Cela semble être corrigé dans iOS 13 GM.

J'ai eu du mal avec la même chose et j'aimerais penser que c'est un bug qui sera résolu d'ici septembre, je l'ai déjà déposé sur Feedback Assistant, assurez-vous de faire de même!

Pour l'instant, vous pouvez simplement créer un nouveau UIHostingController qui encapsule la vue SwiftUI que vous souhaitez afficher de façon modale. Je sais que ça a l'air vraiment hacky mais au moins ça marche:

import SwiftUI

struct OtherView: View {
    @State var otherViewState: String = ""

    var body: some View {
        TextField($otherViewState, placeholder: Text("Demo Text Input"))
    }
}

struct Demo: View {
    var body: some View {
        Button("Toggle Modal") {
            self.showModal()
        }
    }

    func showModal() {
        let window = UIApplication.shared.windows.first
        window?.rootViewController?.present(UIHostingController(rootView: OtherView()), animated: true)
    }
}

Vous voudrez peut-être améliorer la façon dont vous obtenez la fenêtre, surtout si vous prenez en charge plusieurs fenêtres, mais je pense que vous avez l'idée.

1
GuiyeC

Vous pouvez réinitialiser votre Modal dans .onAppear (). Cet exemple fonctionne sur Beta 3.

import SwiftUI

struct ModalView : View {

    @Environment(\.isPresented) var isPresented: Binding<Bool>?

    @State var textName: String = ""

    var body: some View {

        NavigationView {

            Form {
                Section() {
                     TextField("Name", text: self.$textName)
                        .textFieldStyle(.roundedBorder)
                }
            }
            .listStyle(.grouped)
                .navigationBarTitle(Text("Add Name"), displayMode: .large)
                .navigationBarItems(leading: Button(action:{ self.dismiss() })
                { Text("Cancel") },
                                    trailing: Button(action:{ self.dismiss() })
                                    { Text("Save") } )
                .onAppear(perform: {
                    self.textName = ""
                })
        }
    }

    func dismiss() {
        self.isPresented?.value = false
    }

}

struct DetailView : View {

    var body: some View {

        PresentationLink(destination: ModalView())
        { Text("Present") }
    }

}

struct ContentView : View {

    var body: some View {

        NavigationView {
            NavigationLink(destination: DetailView())
            { Text("Navigate") }
        }
    }
}
0
Chuck H