Avoid Nested NavigationTabView

45 Views Asked by At

I'm struggling with something apparently simple. I have a view that arrives with a navigationLink since is not the primary view of my app. In this view i have some links that sends to this view but with different data's. I want to nest those links, but now i'm reciving the double tab View on top. How can I change this? I knwo that I need to toogle the Navigation bar on the second view, but my second view is actually the same view but with different data.

Here's the code

/// ContentView
struct MatchListView: View {
   var namespace: Namespace.ID
   @ObservedObject var dataViewModel = DataViewModel()
   @State private var selectedMatchID: Int?
   @State private var selectedDayIndex: Int = 0
   @State private var headerHeight: CGFloat = 0
   @State private var didFinishFirst = false

   var body: some View {
       ForEach(data.leagues, id: \.id) { league in
           VStack {
               leagueHeader(league: league)
               ForEach(league.matches, id: \.id) { match in
                   matchRow(match: match, namespace: namespace)
               }
            }
           .foregroundStyle(Color.textAccent)
           .background(Color.bgSecondaryAccent)
           .cornerRadius(10)
       }
   }
}

func matchRow(match: Match, namespace: Namespace.ID) -> some View {
   NavigationLink(destination: MatchDetailsView(namespace: namespace, matchID: match.id, homeTeamName: match.home.name, awayTeamName: match.away.name)) { 
       Text("go to match \(match.id)")
   }
}


/// MatchDetails View
struct MatchDetailsView: View {
   NavigationView {  
       List {
           ScrollView(showsIndicators: false) {
               HighlightsView(matchViewModel: matchViewModel)
               MOTMView(matchViewModel: matchViewModel)
               EventsView(matchViewModel: matchViewModel)
               MatchStats(matchViewModel: matchViewModel)
               MatchTopPlayers(matchViewModel: matchViewModel)                       
               TeamFormView(matchViewModel: matchViewModel)
           }        
       }
   }
   .toolbar {
       ShareLink(item: URL(string: "https://maykmayk.github.io/Balun/#/match-details/\(matchID)")!) {
           Label("", systemImage: "square.and.arrow.up")
       }
       Button {
           // action
       } label: {
           Image(systemName: "bell")
       }
       Button {
           // action
        } label: {
           Image(systemName: "star")
       }
   }
   .toolbarRole(.editor)
   .tint(Color(.textAccent))
}


/// TeamformView
struct TeamFormView: View {

   var body: some View {
       NavigationLink(destination: MatchDetailsView(namespace: namespace, matchID: getMatchID(from: match.linkToMatch ?? ""), homeTeamName: match.home?.name ?? "", awayTeamName: match.away?.name ?? "")) {
           Text(match.score ?? "")
               .foregroundColor(.white)
               .font(.system(size: 14, weight: .medium))
               .padding(.horizontal, 5)
               .padding(.vertical, 2.5)
               .background(
                   match.resultString == "W" ? Color.greenAccent :
                   match.resultString == "L" ? Color.redAccent :
                   match.resultString == "D" ? Color.gray.opacity(0.5) :
                   Color.black
               )
               .clipShape(RoundedRectangle(cornerRadius: 6, style: .continuous))
       }
   }
}

My Preview: https://ibb.co/gRHcDSb What I want: https://ibb.co/W6ysFYn

1

There are 1 best solutions below

0
MatBuompy On BEST ANSWER

Posting it as an answere here. The issue you are facing is due to nested NavigationView's. That's why you are seeing more then one navigation bar when navigating to a new screen. Tip: unless you are supporting iOS 15 or older, consider using NavigationStack.

You can edit your code to resemble this:

NavigationView {
    MatchListView(namespace: namespace)
}

MatchListView can stay as it was I guess:

struct MatchListView: View {
   var namespace: Namespace.ID
   //@ObservedObject var dataViewModel = DataViewModel()
   @State private var selectedMatchID: Int?
   @State private var selectedDayIndex: Int = 0
   @State private var headerHeight: CGFloat = 0
   @State private var didFinishFirst = false

   var body: some View {
       ForEach(["Leage 1", "League 2"], id: \.self) { league in
           VStack {
               
               ForEach(["Match 1", "Match 2"], id: \.self) { match in
                   NavigationLink(destination: MatchDetailsView()) {
                          Text("go to match ID")
                    }
               }
            }
           .foregroundStyle(.black)
           .background(.fill)
           .cornerRadius(10)
       }
   }
}

Remove the other NavigationView from here:

struct MatchDetailsView: View {
    
    var body: some View {
        
        /// Remove this NavigationView and others if parents views already have one
        //NavigationView {
            List {
                ScrollView(showsIndicators: false) {
                    //               HighlightsView(matchViewModel: matchViewModel)
                    //               MOTMView(matchViewModel: matchViewModel)
                    //               EventsView(matchViewModel: matchViewModel)
                    //               MatchStats(matchViewModel: matchViewModel)
                    //               MatchTopPlayers(matchViewModel: matchViewModel)
                    TeamFormView()
                }
            }
            
            .toolbar {
                
            }
            .toolbarRole(.editor)
            .tint(.accentColor)
        //}
    }
    
}

I hope this has worked well for you and the explaination was clear!