SwiftUI 와 mvvm 을 경험하면서 정말 덕을 톡톡히 본 두가지 Property Wrapper 에 대해 정리해보자!
UIKit 을 사용했을 때는 어떠한 변수에 변화가 생기면 해당 변화를 직접 관찰하고 반영 해 주어야 했는데 SwiftUI 에서는 property wrapper 를 활용해 이러한 작업을 자동화 할 수 있도록 했다.
@State
속성으로 어떤 프로퍼티의 초기값을 지정했다면, 다른 값으로 재할당 불가, @Binding
변수를 통해서만 가능@State 로 선언된 속성을 다른 뷰에서 사용하려 한다면 @Binding 을 사용해 줄 수 있다. 사용시에는 앞에 $
를 사용해 Bining 변수임을 나타낸다. @State 로 선언된 속성에 변경이 생기면 @Binding 변수에서 이를 인지하고 해당 값에 따른 뷰 변화를 바로 반영할 수 있도록 하는 방식이다.
숫자를 하나씩 높이고 하나의 sheet 를 열어 해당 변화가 적용 되는지를 확인하는 간단한 앱을 통해 적용해 보자!
먼저 결과부터 보자면,
struct ContentView: View {
@State var presenting = false
@State private var number : Int = 167
var body: some View {
VStack {
Text("Number is \(number)")
.fontWeight(.semibold)
.font(.system(size: 30))
.padding(.bottom, 20)
Button(action: {
self.number += 1
}, label: {
Text("Add")
.foregroundColor(.white)
.font(.system(size: 25))
.fontWeight(.bold)
.padding(10)
})
.background(Color.green)
.padding(50)
Button(action: {
self.presenting = true
}, label: {
Text("Move to Check")
.foregroundColor(.white)
.font(.system(size: 25))
.fontWeight(.bold)
.padding(10)
})
.background(Color.blue)
.padding(50)
.sheet(isPresented: self.$presenting){
DetailView(number:
self.$number)
}
}
}
}
struct DetailView: View {
@Binding var number : Int
var body: some View {
Text("Number : \(number)")
}
}
@State 로 선언한 속성 number 의 값이 변하면 해당 변화가 DeatilView 에서 @Binding 되어 자연스레 뷰에 반영되는 것을 확인 할 수 있다!
number가 private이 맞나요? 외부 뷰에서 사용한다고 설명되어있는데... 제가 코린이라 여쭤봅니다.