SwiftUI Landmarks App Tutorial Screen Navigates Back When Toggle Favorite

前端 未结 2 1370
后悔当初
后悔当初 2020-12-02 01:18

I\'m following this SwiftUI tutorial and downloaded the project files.

I built and ran the complete project without any modifications. In the app, if I:

相关标签:
2条回答
  • 2020-12-02 01:54

    Well, actually it is SwiftUI defect, the View being out of view hierarchy must not be refreshed (ie. body called) - it should be updated right after next appearance. (I submitted feedback #FB7659875, and recommend to do the same for everyone affected - this is the case when duplicates are better)

    Meanwhile, below is possible temporary workaround (however it will continue work even after Apple fix the issue, so it is safe). The idea is to use local view state model as intermediate between view and published property and make it updated only when view is visible.

    Provided only corrected view to be replaced in mentioned project.

    Tested with Xcode 11.4 / iOS 13.4 - no unexpected "jump back"

    struct LandmarkList: View {
        @EnvironmentObject private var userData: UserData
    
        @State private var landmarks = [Landmark]() // local model
        @State private var isVisible = false        // own visibility state
        var body: some View {
            NavigationView {
                List {
                    Toggle(isOn: $userData.showFavoritesOnly) {
                        Text("Show Favorites Only")
                    }
    
                    ForEach(landmarks) { landmark in
                        if !self.userData.showFavoritesOnly || landmark.isFavorite {
                            NavigationLink(
                                destination: LandmarkDetail(landmark: landmark)
                                    .environmentObject(self.userData)
                            ) {
                                LandmarkRow(landmark: landmark)
                            }
                        }
                    }
                }
                .onReceive(userData.$landmarks) { array in // observe external model
                    if self.isVisible {
                        self.landmarks = array    // update local only if visible
                    }
                }
                .onAppear {
                    self.isVisible = true         // track own state
                    self.landmarks = self.userData.landmarks
                }
                .onDisappear { self.isVisible = false } // track own state
                .navigationBarTitle(Text("Landmarks"))
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-02 02:03

    this happens because in the "main" list you toggled to "show only favorites". then you change in the detail the favorites (so it is no favorite landmark anymore) and because in swiftui the source of truth was changed (favorite) this item was removed from the main list and so it cannot be shown in the detail anymore because it is no member of the main list anymore, so the detail view just navigates back and show the favorite items only.

    0 讨论(0)
提交回复
热议问题