web-dev-qa-db-fra.com

Présentez une nouvelle vue dans SwiftUI

Je souhaite cliquer sur un bouton, puis présenter une nouvelle vue comme present modally dans UIKit enter image description here

J'ai déjà vu " Comment présenter une nouvelle vue en utilisant des feuilles ", mais je ne veux pas la joindre à la vue principale en tant que feuille modale.

Et je ne veux pas utiliser NavigationLink, car je ne veux pas qu'une nouvelle vue et une ancienne vue aient une relation de navigation.

Merci de votre aide...

11
CH Wing

Pour afficher un modal (style iOS 13)

Vous avez juste besoin d'un simple sheet avec la possibilité de se rejeter:

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

Et présentez-le comme:

struct ContentView: View {
    @State var presentingModal = false

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

Notez que J'ai passé le presentingModal au modal pour que vous puissiez le supprimer du modal lui-même, mais vous pouvez vous en débarrasser.


Pour le rendre VRAIMENT présent fullscreen (Pas seulement visuellement)

Vous devez accéder au ViewController. Vous avez donc besoin de conteneurs d'assistance et de trucs pour l'environnement:

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 }
    }
}

Ensuite, vous devez utiliser implémenter cette extension:

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)
    }
}

Finalement

vous pouvez le faire fullscreen comme:

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
            }
        }
    }
}
10
Mojtaba Hosseini

Voici une vue à sens unique simple. C'est très simple.

        struct ChildView: View{
           private  let colors: [Color] = [.red, .yellow,.green,.white]
           @Binding var index : Int
           var body: some View {
           let next = (self.index+1)  % MyContainer.totalChildren
             return   ZStack{
                    colors[self.index  % colors.count]
                     Button("myNextView \(next)   ", action: {
                    withAnimation{
                        self.index = next
                    }
                    }
                )}.transition(.asymmetric(insertion: .move(Edge: .trailing)  , removal:  .move(Edge: .leading)  ))
            }
        }

        struct MyContainer: View {
            static var totalChildren = 10
            @State private var value: Int = 0
            var body: some View {
                    HStack{
                        ForEach(0..<(Self.totalChildren) ) { index in
                            Group{
                            if    index == self.value {
                                ChildView(index:  self.$value)
                                }}
                            }
                }
                }
        }
0
E.Coms