135 votes

Utiliser la vue sous condition dans SwiftUI

J'essaie de trouver la bonne façon d'inclure conditionnellement une vue avec swiftui. Je n'ai pas pu utiliser le if directement dans une vue et j'ai dû utiliser un vue de la pile pour le faire.

Cela fonctionne, mais il semble qu'il y aurait un moyen plus propre.

 var body: some View {
    HStack() {
        if keychain.get("api-key") != nil {
            TabView()
        } else {
            LoginView()
        }
    }
}

187voto

Yurii Kotov Points 1544

La façon la plus simple d'éviter d' utiliser un conteneur supplémentaire comme HStack est annoter votre body immobilier en @ViewBuilder , comme ceci:

 @ViewBuilder
var body: some View {
    if user.isLoggedIn {
        MainView()
    } else {
        LoginView()
    }
}

13voto

Mike Glukhov Points 49

Quoi qu'il en soit, le problème existe toujours. Penser à mvvm comme tous les exemples sur cette page le casse. Logique de l'interface utilisateur contenue dans View. Dans tous les cas, il n'est pas possible d'écrire un test unitaire pour couvrir la logique.

PS. Je ne peux toujours pas résoudre ce problème.

METTRE À JOUR

J'en ai terminé avec la solution,

Voir la fiche:

 import SwiftUI


struct RootView: View {

    @ObservedObject var viewModel: RatesListViewModel

    var body: some View {
        viewModel.makeView()
    }
}


extension RatesListViewModel {

    func makeView() -> AnyView {
        if isShowingEmpty {
            return AnyView(EmptyListView().environmentObject(self))
        } else {
            return AnyView(RatesListView().environmentObject(self))
        }
    }
}

6voto

Michael St Clair Points 948

Sur la base des commentaires, j'ai fini par opter pour cette solution qui régénérera la vue lorsque la clé api changera en utilisant @EnvironmentObject.

UserData.swift

 import SwiftUI
import Combine
import KeychainSwift

final class UserData: BindableObject  {
    let didChange = PassthroughSubject<UserData, Never>()
    let keychain = KeychainSwift()

    var apiKey : String? {
        get {
            keychain.get("api-key")
        }
        set {
            if let newApiKey : String = newValue {
                keychain.set(newApiKey, forKey: "api-key")
            } else {
                keychain.delete("api-key")
            }

            didChange.send(self)
        }
    }
}

ContentView.swift

 import SwiftUI

struct ContentView : View {

    @EnvironmentObject var userData: UserData

    var body: some View {
        Group() {
            if userData.apiKey != nil {
                TabView()
            } else {
                LoginView()
            }
        }
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X