我的应用程序中有一个TabView,用于显示四个屏幕。两者相似,但数据源不同。如果单击第一个选项卡(EventsScreen),然后单击第三个选项卡(MyBagScreen),一切正常。如果我单击第一个选项卡(EventsScreen),然后单击第二个选项卡(EventsScreen),它将仅加载空白屏幕(我假设它仅加载背景)。它们是两个不同的对象,为什么这不起作用?
AppView.swift
struct AppView: View {
var body: some View {
TabView {
EventsScreen().environmentObject(EventsViewModel(repo: IncentivesRespository()))
.tabItem {
Text("Barter")
Image("icon_barter")
}
EventsScreen().environmentObject(EventsViewModel(repo: OpportunityRepository()))
.tabItem {
Text("Earn")
Image("icon_earn")
}
MyBagScreen().environmentObject(MyBagViewModel())
.tabItem{
Text("My Bag")
Image("icon_bag")
}
AccountScreen().environmentObject(AccountViewModel())
.tabItem {
Text("Account")
Image("icon_account")
}
}
.onAppear(perform: {
UITabBar.appearance().backgroundColor = .black
})
.navigationBarHidden(true)
}
}
EventsScreen
struct EventsScreen: View {
@EnvironmentObject
var viewModel: EventsViewModel
let calendarManager = RKManager(calendar: Calendar.current, minimumDate: Date(), maximumDate: Date().addingTimeInterval(60*60*24*90), mode: 1)
@State
var currentPage: Int = 0
@State
private var searchTerm : String = ""
init() {
UITableView.appearance().separatorStyle = .none
}
var body: some View {
GeometryReader { geometry in
List {
ZStack(alignment: .top) {
EventViewController(controllers: self.viewModel.featureEventControllers, currentPage: self.$currentPage)
VStack {
SearchBar(text: self.$searchTerm)
.padding(EdgeInsets.init(top: 16, leading: 16, bottom: 0, trailing: 16))
HStack {
Spacer()
Chip(text: "Dates", action: {
self.viewModel.showDateSelection.toggle()
})
.sheet(isPresented: self.$viewModel.showDateSelection, onDismiss: {
self.viewModel.onDatesSelected(startDate: self.calendarManager.startDate, endDate: self.calendarManager.endDate)
}, content: {
RKViewController(isPresented: self.$viewModel.showDateSelection, rkManager: self.calendarManager)
})
Chip(text:"Type", action: {
self.viewModel.showTypeSelection.toggle()
})
Chip(text: "Points", action: {
self.viewModel.showPointsSelection.toggle()
})
Spacer()
}
}
}.listRowInsets(EdgeInsets())
.frame(height: 600)
ForEach(self.viewModel.eventSections.indices) { id in
EventSectionView(eventSection: self.viewModel.eventSections[id])
}
.listRowBackground(Color.black)
}
.navigationBarTitle(Text("Events"), displayMode: .inline)
.navigationBarHidden(true)
if self.viewModel.showPointsSelection {
EventsPointsRangeBottomSheet(isOpen: self.$viewModel.showPointsSelection, selectedRange: self.$viewModel.selectedRange, range: 0.0...self.viewModel.maxPoints, action: {
self.viewModel.onPointsSelected()
})
}
if self.viewModel.showTypeSelection {
TypeBottomSheet(categories: self.viewModel.allCategories, isOpen: self.$viewModel.showTypeSelection, selectedCategoryUuids: self.$viewModel.selectedCategoryUuids, action: {
self.viewModel.onTypesSelected()
})
}
}
}
}
答案 0 :(得分:2)
您的代码快照不可测试,因此只是一个想法-您必须对其进行测试。
因此,假设您第二个视图的环境对象是正确的,请尝试使用.id
修饰符使它们对于视图来说是唯一的,如下所示
TabView {
EventsScreen().environmentObject(EventsViewModel(repo: IncentivesRespository()))
.id(1) // << here !!
.tabItem {
Text("Barter")
Image("icon_barter")
}
EventsScreen().environmentObject(EventsViewModel(repo: OpportunityRepository()))
.id(2) // << here !!
.tabItem {
Text("Earn")
Image("icon_earn")
}
...
注意::我在.navigationBarHidden(true)
中看到用法AppView
-如果这意味着您要将TabView
包含在NavigationView
中,则不要这样做-您将无法使用它。 TabView设计为仅 root视图。如果需要导航,请将其放在 标签内。