[SwiftUI] 데이터 변경 후 뷰 종료 버그

Page·2022년 6월 18일
1

SwiftUI

목록 보기
11/18
post-thumbnail
post-custom-banner

문제

이전에 작성한 데이터 값 변경하기에서 발생한 버그다. 즐겨찾기 버튼을 누르면 View가 꺼져버리는 문제가 있었다. View Hierarchy를 벗어난 View에서 Refresh가 일어나면 이런 일이 발생한다.

다시 정리하자면 NavigationView로 전환한 후 즐겨찾기 버튼을 누르면 List를 보여주고 있는 View에서 Propery wrapper로 선언되지 않은 데이터가 변경되서 발생하는 버그다. 애플의 공식 가이드에 있는 튜토리얼인데 이런 버그가 있다는게 아쉽다.

var fillteredLanMarks: [LandMarkModel] {
    landmarkViewModel.landmarks.filter { landmark in
        (!showFavoritesOnly || landmark.isFavorite)
    }
}

이게 문제의 코드인데, 만약 즐겨찾기 버튼을 누르면 filter에 들어오는 값이 바뀌게 되고 결과적으로 filteredLandMarks가 변하게 된다.

해결

@State private var lastShowFavoritesOnly = true
@State private var showFavoritesOnly = true
@EnvironmentObject var landmarkViewModel: LandmarkViewModel

var fillteredLanMarks: [LandMarkModel] {
    landmarkViewModel.landmarks.filter { landmark in
        (!showFavoritesOnly || landmark.isFavorite)
    }
}
// 생략 

List {
   // 생략 
}
.onDisappear {
    lastShowFavoritesOnly = showFavoritesOnly
    showFavoritesOnly = false
}
.onAppear {
    showFavoritesOnly = lastShowFavoritesOnly
}

내 솔루션은 간단히 filteredLandMarks가 Refresh되지 않도록 막는 것이다. 뷰를 벗어날 때 showFavorites가 false가 된다면 filteredLandMarks에는 모든 landmark가 저장될 것이고 나중에 각 landmark의 isFavortie 값이 바뀐대도 변경될 일이 없다.
대신 마지막에 즐겨찾기만 보고 있었는지, 모두 보고 있었는지만 저장해서 뷰를 다시 그릴 때 그 값을 가져오도록 해줬다.

그냥 filteredLandMarks에 @State 붙이면 되는거 아니야? 라고 생각했는데 Computed Property를 Property Wrapper에 적용할 수 없다며 문제가 생긴다.

현재 트위터 클론코딩에서도 비슷한 문제를 겪고 있었는데 같은 원인인지 한번 찾아봐야겠다.

이제 문제없이 동작하고 있다.
아래 다른 솔루션도 추가했으니 읽어보면 도움이 될것이다.

References

https://stackoverflow.com/questions/61094219/swiftui-landmarks-app-tutorial-screen-navigates-back-when-toggle-favorite

post-custom-banner

0개의 댓글