首页 > 解决方案 > SwiftUI 和双导航栏

问题描述

我在 SwiftUI 中的导航栏遇到问题。我有 3 个观点:

我知道您应该在导航中只有一个导航视图,而我在内容视图中拥有。

但是,如果我从 ViewOne > ViewTwo > ViewThree 然后返回 ViewTwo 我会得到这样的双导航栏

双导航视图

这是我的代码:

ViewOne

import SwiftUI

struct ContentView: View {
    
    @State private var activateNavigationLink: Bool = false // Required to navigate back to this view after deleting a trip
    
    var body: some View {
        
        TabView {
            
            NavigationView {
                ViewTwo()
            }.tabItem{
                Image(systemName: "airplane")
                Text("Trips")
            }
            
            NavigationView {
                ViewThree(activateNavigationLink: $activateNavigationLink)
            }
            .tabItem{
                Image(systemName: "location.fill")
                Text("Nearby")
            }
        }
    }
}

视图二

import SwiftUI

struct ViewTwo: View {
    
    @State private var cityName: String = ""
    @State private var action: Int? = 0
    @Binding var activateNavigationLink: Bool // Required to navigate back to itinerary view after deleting a trip
    @StateObject var selectCityVM = SelectCityViewModel()
    @Environment(\.managedObjectContext) private var viewContext
    @State private var showingAlert = false
    @StateObject var locationVM = UserLocationViewModel()
    
    @State var trip: Trip? = nil
    
    @State var location: Destination? = nil {
        didSet {
            
            if let name = location?.city {
                cityName = name // Set city name for navbar
                print(cityName)
            }
        }
    }
    
    let categories = ["Food", "Things to do", "Nightlife", "Need to know"] // Category tile names
    
    let columns = [GridItem(.adaptive(minimum: 150))] // Adjust column layout here
    
    var body: some View {
        
        VStack {
            
            VStack { // Needed to navigate to trip edit screen
                NavigationLink(destination: CreateTripView(activateNavigationLink: $activateNavigationLink, trip: trip), tag: 1, selection: $action) {
                    EmptyView()
                }
            }
            
            // check if saved trip or nearby query
            if trip != nil {
                HStack {
                    // Displays trip start and end dates
                    if let tripStartDate = trip?.startDate {
                        if let tripEndDate = trip?.endDate {
                            
                            // Displays trip start and end dates
                            Text("\(currentYearDate.string(from: tripStartDate)) - \(futureYearDate.string(from: tripEndDate))")
                                .padding(.bottom, 3)
                        }
                    }
                    Spacer()
                }.padding(.leading)
            }
            Spacer()
            
            ScrollView {
                // Displays category tiles
                LazyVGrid(columns: columns, spacing: 30) {
                    
                    ForEach(categories, id: \.self) { category in
                        
                        switch category {
                        case "Need to know": // Show country info
                            NavigationLink(destination: DestinationInfoView(trip: trip)) {
                                CategoryCard(category: category)
                            }
                        default: // Search yelp
                            NavigationLink(destination: ViewThree(selectedCategory: category, trip: trip, location: location)) {
                                CategoryCard(category: category)
                            }
                        }
                    }
                }
            }.padding(.top)
            
            Spacer()
                
                .toolbar {
                    ToolbarItem(placement: .navigationBarTrailing) {
                        
                        if trip != nil {
                            Menu {
                                // Edit trip
                                Button("Edit trip") {
                                    action = 1 // Navigate to trip edit screen
                                }
                                // Delete trip
                                Button("Delete trip") {
                                    showAlert() // Show alert to confirm deletion of trip
                                }
                            } label: {
                                Image(systemName: "ellipsis.circle")
                                    .font(.title2)
                            }
                            
                        }
                        
                    }
                }
                .navigationTitle("\(cityName ) \(selectCityVM.getFlag(from: trip?.iso2 ?? ""))")
        }
       
        
        // Show alert to confirm deletion of trip
        .alert(isPresented:$showingAlert) {
            Alert(
                title: Text("Are you sure you want to delete this?"),
                message: Text("There is no undo"),
                primaryButton: .destructive(Text("Delete")) {
                    deleteTrip()
                },
                secondaryButton: .cancel()
            )
        }
    }

视图三

import SwiftUI

struct ViewThree: View {
    
    @ObservedObject var yelpVM = YelpSearchViewModel()
    @State private var showingLocationAlert = false
    
    @State var selectedCategory: String = ""
    
    var trip: Trip?
    var location: Destination?
    
    var body: some View {
        
        VStack {
            
            if yelpVM.places.isEmpty { // Show loading view
                
                Spacer()
                VStack {
                    ProgressView()
                        .scaleEffect(1.5, anchor: .center)
                        .padding()
                    
                    Text("Finding local \(selectedCategory.lowercased())...").padding(5)
                }
                Spacer()
                
            } else {
                
                ScrollView {
                    LazyVStack {
                        if let fetchedPlacess = yelpVM.places {
                            
                            ForEach(fetchedPlacess, id: \.identifier) { place in
                                
                                NavigationLink(destination: BusinessDetailsView(business: place)) {
                                    ListingCardView(business: place)
                                    
                                }.buttonStyle(PlainButtonStyle())
                                
                                .onAppear(perform: {
                                    
                                    // Get more restaurants from yelp if the user has reached the end of current page
                                    if place == yelpVM.places.last {
                                        yelpVM.getLocalPlaces(category: selectedCategory, latitude: place.coordinates?.latitude ?? 0, longitude: place.coordinates?.longitude ?? 0)
                                    }
                                })
                            }
                        }
                    }
                }
            }
        }.navigationTitle(selectedCategory)
        .onAppear(perform: {
            if trip != nil {
                if let unwrappedTrip = trip {
                    
                    if yelpVM.places.isEmpty {
                        yelpVM.getLocalPlaces(category: selectedCategory, latitude: unwrappedTrip.latitude, longitude: unwrappedTrip.longitude)
                    }
                }
                
            } else {
                if let unwrappedlocation = location {
                    if yelpVM.places.isEmpty {
                        yelpVM.getLocalPlaces(category: selectedCategory, latitude: unwrappedlocation.latitude, longitude: unwrappedlocation.longitude)
                    }
                }
            }
        })
        
    }
}

这一直让我发疯。任何帮助或指导将不胜感激。

标签: swiftswiftuiswiftui-navigationview

解决方案


您可以尝试将其中一个视图放在 a.sheet()中以摆脱双导航栏。


推荐阅读