SwiftUI 和双导航栏

Posted

技术标签:

【中文标题】SwiftUI 和双导航栏【英文标题】:SwiftUI and double navigation bar 【发布时间】:2021-09-04 04:11:56 【问题描述】:

我在使用 SwiftUI 中的导航栏时遇到问题。我有 3 个视图:

ViewOne:包含导航视图和两个选项卡视图 ViewTwo:包含多个导航链接 ViewThree:包含多个导航链接

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

但是,如果我从 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)
                    
                
            
        )
        
    

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

【问题讨论】:

你能加入minimal reproducible example吗? 【参考方案1】:

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

【讨论】:

【参考方案2】:

我无法复制您的问题,因为代码缺少某些元素。 但是,只使用如下所示的 1 个 NavigationView 是否适合您:

struct ContentView: View 
    @State private var activateNavigationLink: Bool = false

    var body: some View 
        NavigationView 
            TabView 
                ViewTwo()
                    .tabItem
                        Image(systemName: "airplane")
                        Text("Trips")
                    
                ViewThree(activateNavigationLink: $activateNavigationLink)
                    .tabItem
                        Image(systemName: "location.fill")
                        Text("Nearby")
                    
            
        
    

【讨论】:

以上是关于SwiftUI 和双导航栏的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI 搜索栏与导航栏一致

SwiftUI 中的 QLPreviewController 缺少导航栏

Objective C 到 SwiftUI 隐藏导航栏

在 SwiftUI 中的多个导航视图的情况下隐藏导航栏

SwiftUI - 设置状态栏背景颜色以与导航栏对齐

如何从导航栏按钮导航到新视图在 SwiftUI 中单击