본문 바로가기

코딩의 유익함/스위프트(Swift)

SwiftUI - @State와 @Binding 알아보기

그림1) @State, @Binding

SwiftUI에서는 기본적으로 구조체에서 View프로토콜을 구현하여 View(사용자 화면)를 다룹니다. Xcode에서 프로젝트를 만들 때 SwiftUI를 선택하면 ContentView 구조체가 생성되고 여기서 뷰를 다룹니다.

 

그런데 이 ContentView 구조체 안에서 var 키워드로 선언한 프로퍼티의 값을 구조체 내(보통 body 프로퍼티)에서 변경하려고 하면 에러가 뜹니다. 즉, 변경할 수 없다는 것인데요. 왜 그런 것일까요?

 

그림2) @State, @Binding

Swift의 구조체에서 mutating으로 선언되지 않은 연산 프로퍼티는 구조체 내부에서 그 값의 변경이 불가합니다. 그러면 연산 프로퍼티인 body를 mutating으로 선언해주면 될까요? 안됩니다.

 

View 프로토콜의 body 프로퍼티는 { get } 으로 되어 있으며, 이는 nonmutating 으로 구현을 요구합니다. 그렇다면 변수 변경은 아예 불가능한 것일까요? 그것은 아닙니다. @State라는 속성을 이용하면 가능합니다.

 

그림3) @State, @Binding

프로퍼티에 @State 속성을 부여했더니, 에러가 사라진 것을 볼 수 있습니다. @State는 어떤 역할을 하는 것일까요? 구조체 내부에서 강제로 변경이 가능하도록 해주는 속성일까요? 아닙니다.

 

@State는 단어 그대로 현재 상태를 나타내는 속성으로써 뷰의 어떤 값을 저장하는 데 사용합니다. 그리고 현재 뷰 UI의 특정 상태를 저장하기 위해 만들어진 것이기 때문에 보통 Private로 지정하여 사용합니다. 

 

그런데 그림3을 실행해 보시면 아시겠지만, 프리뷰 화면에는 그대로 Test로 뜨는 것을 볼 수 있는데요. 분명 Test2로 변경했는데 말이지요. 사실 @State 속성의 프로퍼티의 값은 재 할당하여 값을 바꿀 수 없습니다.

 

여러 테스트 결과, @State 속성으로 어떤 프로퍼티의 초기값을 지정해주었다면, 다시 다른 값으로 재 할당을 하더라도 변경되지 않습니다. @Binding 변수를 통해서만 변경이 가능합니다.

 

그림4) @State, @Binding

@Binding은 단어 그대로 구속력이 있는, 묶여 있는 뜻인데요. @State 속성으로 선언된 프로퍼티와 연결되어 있다고 생각하시면 될 듯합니다. 다른 뷰에서 해당 프로퍼티를 사용한다면 @Binding 속성을 사용합니다.

 

@State는 반드시 주가 되는 뷰에 한 번 선언해주고, 이 프로퍼티를 다른 뷰들에서 사용하기 위해서는 @Binding을 사용합니다. 그리고 사용시에는 $를 앞에 붙여주어 Binding 변수임을 나타냅니다.

 

그리고 뷰 UI에서 특정 동작으로 해당 프로퍼티 값이 변경되는 자리에는 앞에 $를 붙여주고, 코드 내에서 그 값 자체를 출력하여 뷰 UI에 보여주려고 할 때에는 붙이지 않고 그대로 사용합니다.

 

여기까지 잘 이해가 되셨나요? 저도 테스트를 하면서 작동하는 구조를 파악한 것인데, 혹시 잘못된 점이 있거나 의문이 있으시면 말씀 부탁드립니다. 감사합니다.