SwiftUI는 구조체에서 View프로토콜을 구현하여 View(사용자화면)을 다룬다. Xcode에서 프로젝트를 만들 때 SwiftUI를 선택하면 ContentView구조체가 생성되고 여기서 뷰를 다룬다.
이 ContentView에서 var키워드로 선언한 프로퍼티의 값을 body프로퍼티 내에서 변경하려고 하면 에러가 뜬다.
Swift의 구조체에서 mutating으로 선언되지 않은 연산프로퍼티는 구조체 내부에서 그 값의 변경이 불가능하다. 그러면 연산 프로퍼티인 body를 mutating으로 선언해주면 되는가? 아니다.
View프로토콜의 body프로퍼티는 { get } 으로 되어있으며, 이는 nomutating으로 구현을 요구한다. 이 때 변수변경은 @State라는 속성을 이용하면 된다.
프로퍼티에 @State속성을 부여하면 에러가 사라진다.
@State는 단어 그대로 현재 상태를 나타내는 속성으로써 뷰의 어떤 값을 저장하는데 사용한다. 그리고 현재 뷰UI의 특정 상태를 저장하기 위해 만들어진 것이기 때문에 보통 Private로 지정하여 사용한다.
@State속성의 프로퍼티는 재 할당하여 값을 바꿀 수 없다.
아래의 코드.
struct ContentView: View{
@State private var test: String = "test"
var body: some View{
self.test = "test2"
return
Text(test)
}
}
//결과: test
바꿀 수 없기 떄문에 test로 나온다.
이런 값을 변경하기 위해선 @Binding변수를 통해서 가능하다.
@Binding은 단어 그대로 구속력이 있는, 묶여있는 뜻인데, @State속성으로 선언된 프로퍼티와 연결되어 있다고 생각하면 된다.
다른 뷰에서 해당 프로퍼티를 사용한다면 @Binding을 사용한다,.
@State는 반드시 주가 되는 뷰에 한 번 선언해주고, 이 프로퍼티를 다른 뷰들에서 사요하기 위해서는 @Binding을 사용한다. 그리고 사용시에는 $를 앞에 붙여주어 Binding변수임을 나타낸다 그리고 뷰 UI에서 특정 동작으로 해당 프로퍼티 값이 변경되는 자리에는 앞에 $를 붙여주고, 코드 내에서 그 값 자체를 출력하여 뷰 UI에 보여주려고 할 때에는 붙이지 않고 그대로 사용한다.
출처
https://value-of-life.tistory.com/160