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 和双导航栏的主要内容,如果未能解决你的问题,请参考以下文章