0
votes

Comment créer une Tabview personnalisée avec NavigationView à Swiftui?

[modifier] - Cette question a été modifiée et simplifiée.

J'ai besoin de créer une Tabview CustomLooking à la place de la valeur par défaut.

Voici mon code complet avec le problème. Il suffit d'exécuter le code ci-dessous. xxx

sur l'onglet # 1 Cliquez sur la navigation. Passer à l'onglet n ° 2, puis revenez à l'onglet n ° 1. Vous verrez que l'onglet n ° 1 est apparu à la racine.

Comment puis-je empêcher la CustomTabview de sauter de rooter à chaque fois que je chante des onglets?


0 commentaires

3 Réponses :


0
votes

Je pense qu'il est possible même avec votre point de vue personnalisé, car le problème est dans la reconstruction exploretab () code> lorsque vous changez des onglets, tout le contenu de cet onglet est donc reconstruit, donc interne NavigationView code> sur Recuilt est sur la première page.

En supposant que vous n'avez qu'un seul Exploretab code> dans votre application (comme cela devrait être évident), la solution possible consiste à le faire Équatiftable code> explicitement et n'autorise pas SWIFTUI de le remplacer sur actualiser. P>

SO P>

struct ExploreTab: View, Equatable {
    static func == (lhs: Self, rhs: Self) -> Bool {
        return true    // prevent replacing ever !!
    }

    var body: some View {
       NavigationView {
            NavigationLink("Go", destination: Text("Explore"))
       }
    }
}

enum TestTabs {
    case explore
    case network
}

struct CustomTabView: View {
    @Binding var displayedTab: TestTabs
    var body: some View {
        HStack {
            Button("Explore") { displayedTab = .explore }
            Divider()
            Button("Network") { displayedTab = .network }
        }
        .frame(maxWidth: .infinity)
        .frame(height: 80).background(Color.yellow)
    }
}

struct TestCustomTabView: View {
    @State private var displayedTab = TestTabs.explore

    var body: some View {
        VStack(spacing: 0) {
            switch displayedTab {
                case .explore: ExploreTab().equatable()      // << here !!
                case .network: Text("NetworkTab").frame(maxWidth: .infinity, maxHeight: .infinity)
            }
            CustomTabView(displayedTab: $displayedTab)   //This is the Custom TabBar
        }

        .edgesIgnoringSafeArea(.bottom)
    }
}


3 commentaires

Hmm. Cela n'a pas fonctionné. Lorsque j'ai cliqué sur un autre onglet, puis cliquez dessus, la vue semblait toujours être remplacée, car elle était de retour à la racine.


Avez-vous une copie des fichiers de ce projet sur Github? J'ai littéralement copié le code que vous avez fourni mais il fait toujours apparaître pour racine. J'ai xcode 12 bêta et je teste sur la 2e génération iphonee. Cela ne fonctionne toujours pas pour moi: / Je suis confus.


Voici un fichier zip de mon projet XCode12. Est-ce que ça marche pour toi? -> Fichier ZIP



1
votes

Le problème est que l'état Isactive de navigation n'est pas enregistré, ainsi que l'état de l'onglet affiché.

En enregistrant l'état de la navigation de chaque onglet ainsi que dans lequel l'onglet est actif, l'état de navigation correct peut être disponible pour Chaque onglet.

Le modèle peut être amélioré pour éliminer le tuple et le rendre plus flexible, mais la principale chose est l'utilisation de getter et de setter pour utiliser un modèle encapsulé de l'état de navigation pour chaque onglet afin de permettre à la navigationLink de la mettre à jour via une liaison.

J'ai simplifié le niveau de vstack de niveau supérieur et supprimé le commutateur de niveau supérieur comme il n'est pas nécessaire ici, mais il peut être ajouté pour utiliser différents types de vues Au niveau supérieur dans une réelle implémentation


xxx

0 commentaires

1
votes

Tout ce dont vous avez besoin est une ZStack avec opacité.

import SwiftUI

enum TabName {
    case explore, network
}

struct ContentView: View {
    @State var displayedTab: TabName = .explore
    var body: some View {
        VStack {
            ZStack {
                AViewWhichNavigates(title: "Explore")
                    .background(Color.green)
                    .opacity(displayedTab == .explore ? 1 : 0)
                AViewWhichNavigates(title: "Network")
                    .background(Color.green)
                    .opacity(displayedTab == .network ? 1 : 0)
            }
            CustomTabView(displayedTab: $displayedTab)
        }
    }
}

struct CustomTabView: View {
    @Binding var displayedTab: TabName
    var body: some View {
        HStack {
            Spacer()
            Text("Explore").border(Color.black, width: 1).onTapGesture { self.displayedTab = .explore }
            Spacer()
            Text("Network").border(Color.black, width: 1).onTapGesture { self.displayedTab = .network }
            Spacer()
        }
    }
}

struct AViewWhichNavigates: View {
    let title: String
    var body: some View {
        NavigationView(content: {
            NavigationLink(destination: Text("We are one level deep in navigation")) {
                Text("You are at root. Tap to navigate").navigationTitle(title)
            }
        })
    }
}


0 commentaires