[SwiftUI] 여러 뷰에 중복되는 데이터를 관리하는 방법

frogKing·2022년 1월 15일
0

배경

부모 뷰에서 Edit 버튼을 누르면 자식 뷰로 이동한다고 가정하자. 이 때 자식 뷰에서는 부모 뷰 배경의 색을 바꾸는 기능을 넣을 것이다. 그렇다면 자식 뷰에서 변경한 배경 색을 어떻게 부모 뷰에 전달해서 부모 뷰의 배경 색을 바꿀 수 있을까?

방법

먼저 SSOT(Single Source of Truth)의 개념을 알아야 한다. 예를 들어서, 어떤 데이터를 부모 뷰에서도 사용하고, 자식 뷰에서도 사용한다고 가정하자. 만약 SSOT의 개념을 모르는 사람이라면 부모 뷰에도 특정 데이터를 저장하고, 자식 뷰에도 특정 데이터를 저장할 것이다. 이렇게 하면 데이터가 여러 곳에 저장되어 있어서 버그를 유발한다. 하지만 부모 뷰에서 SOT라는 저장소를 만들어두면, 부모 뷰에서도 접근할 수 있고 자식 뷰에서도 접근할 수 있다. 심지어 자식 뷰에서 SOT에 있는 값을 변경하면 부모 뷰는 이를 알아채고 뷰를 최신화할 수 있다.

간단히 설명하고 자세한 내용은 위 링크를 참고하자. 우선 @State라는 프로퍼티를 사용하면 해당 프로퍼티가 선언된 뷰에 SOT를 만든다. 아래와 같이 선언할 수 있다.

@State private var name = "Amy" // "Amy"라는 이름을 SOT에 저장

부모 뷰는 화면에 이름을 띄워놓는다고 가정해보자. 그렇다면 얼추 이런 식으로 코드를 구성할 수 있다.

struct MeetingView: View {
		@State private var name = "Amy"
    var body: some View {
				Text($name)
		}
}

name 앞에 $를 붙인 이유는 바인딩된 값을 붙여주어야 name이 바뀌었을 때, 이를 알아채고 뷰를 업데이트할 수 있기 때문이다.

따라서 자식 뷰를 호출할 때도 $를 붙여서 바인딩된 값을 건내주어야 자식 뷰도 SOT에 접근이 가능하다.

struct DetailView: View {
		... // 생략
		@State private var name = "Amy"
    var body: some View {
				Text($name)
		}

    var body: some View {
        List{
            ... // 생략
        }
        .sheet(isPresented: isPresentingEditView){
            NavigationView {
                DetailEditView(data: $data) // 자식 뷰를 호출할 때도 $를 붙여준다.

이제 자식 뷰를 살펴보겠다.

struct DetailEditView: View {
    @Binding var name: String
    
    var body: some View {
        TextField("Name", text: $name)
				... // 생략
    }
}

TextField로 이름을 변경해줄 수 있는데 변경한 다음 부모 뷰로 가게 되면 부모 뷰 또한 변경한 이름으로 바뀌어 있는 것을 볼 수 있다. 이는 SOT에 저장된 값을 건드렸기 때문에 $를 달고 있는 모든 값들은 값이 변경되었을 때 update가 되는 것을 확인할 수 있다.

profile
내가 이걸 알고 있다고 말할 수 있을까

0개의 댓글