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

时间:2020-09-20 11:40:29

标签: swift swiftui

我有TabView包含2个条目。...都触发显示StationListView。我遇到的问题是,当我单击第二个选项卡时,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的完整代码

1 个答案:

答案 0 :(得分:1)

您希望视图在被选中后从网络中重新加载数据。不幸的是,.onAppear无法正常工作,因为您选择视图时未将其加载。

相反,当selection更改时,重新加载数据。

要在SwiftUI 2.0(Xcode 12)中实现此功能,请将tag数字和selection(作为Binding)传递给StationListView,然后使用{{当StationListViewtag都与selection都匹配时,以及.onAppear使用selection进行更改时,重新加载数据:

onChange(of: selection)

这里是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