如果视图相同,则TabView生命周期问题



我有包含2个条目的TabView。。。。两者都触发CCD_ 2的显示。我遇到的问题是,当我点击第二个选项卡时,onAppear被调用两次(两个实例各调用一次(,第二个标签的数据显示出来,紧接着第一个标签又显示了数据。

struct ContentView : View {
@ObservedObject var cityBikesViewModel = CityBikesViewModel(repository: CityBikesRepository())
@State private var selection = 0

var body: some View {
TabView(selection: $selection) {
StationListView(cityBikesViewModel: cityBikesViewModel, network: "galway")
.tabItem {
VStack {
Image(systemName: "location")
Text("Galway")
}
}.tag(0)
StationListView(cityBikesViewModel: cityBikesViewModel, network: "oslo-bysykkel")
.tabItem {
VStack {
Image(systemName: "location")
Text("Oslo")
}
}.tag(1)
}
}
}
struct StationListView: View {
@ObservedObject var cityBikesViewModel : CityBikesViewModel
var network: String

var body: some View {
NavigationView {
List(cityBikesViewModel.stationList, id: .id) { station in
StationView(station: station)
}
.navigationBarTitle(Text("Bike Share"))
.onAppear(perform: {
self.cityBikesViewModel.fetch(network: self.network)
})
}
}
}

完整代码位于https://github.com/joreilly/BikeShare/blob/master/ios/BikeShare/BikeShare/ContentView.swift

您希望视图在被选中时从网络中重新加载数据。不幸的是,.onAppear不起作用,因为当你选择它时,视图没有加载。

相反,请在selection发生更改时重新加载数据。

要在SwiftUI 2.0(Xcode 12(中实现这一点,请将tag编号和selection(作为Binding(传递给StationListView,然后当tagselection匹配时(.onAppearselection使用onChange(of: selection):更改时(,让StationListView重新加载数据

struct StationListView: View {
@ObservedObject var cityBikesViewModel : CityBikesViewModel
var network: String
var tag: Int
@Binding var selection: Int

var body: some View {
NavigationView {
List(cityBikesViewModel.stationList, id: .id) { station in
StationView(station: station)
}
.navigationBarTitle(Text("Bike Share"))
.onChange(of: selection) { _ in
refreshData()
}
.onAppear {
refreshData()
}
}
}

func refreshData() {
if tag == selection {
cityBikesViewModel.fetch(network: self.network)
}
}
}

这是TabView:

TabView(selection: $selection) {
StationListView(cityBikesViewModel: cityBikesViewModel, network: "galway", tag: 0, selection: $selection)
.tabItem {
VStack {
Image(systemName: "location")
Text("Galway")
}
}.tag(0)
StationListView(cityBikesViewModel: cityBikesViewModel, network: "oslo-bysykkel", tag: 1, selection: $selection)
.tabItem {
VStack {
Image(systemName: "location")
Text("Oslo")
}
}.tag(1)
}
}

最新更新