SwiftUI에서 관리하는 값을 읽고 쓸 수 있는 속성 래퍼
private
으로 선언되어 init
으로 초기화되는 것을 방지하고, 외부에서 사용되지 않음wrappedValue
속성 사용$
를 붙이면 바인딩을 가져올 수 있음struct PlayButton: View {
@State private var isPlaying: Bool = false // Create the state.
var body: some View {
Button(isPlaying ? "Pause" : "Play") { // Read the state.
isPlaying.toggle() // Write the state.
}
}
}
@State인 isPlaying
이 변경 ~~> 버튼의 레이블 변경
source of truth가 소유한 값을 읽고 쓸 수 있는 속성 래퍼
struct PlayerView: View {
@State private var isPlaying: Bool = false
var body: some View {
PlayButton(isPlaying: $isPlaying) // Pass a binding.
}
}
struct PlayButton: View {
@Binding var isPlaying: Bool
var body: some View {
Button(isPlaying ? "Pause" : "Play") {
isPlaying.toggle()
}
}
}
상위 뷰(PlayerView)에서 전달한 @State를 하위 뷰(PlayButton)에서 @Binding으로 사용
ObservableObject를 인스턴스화하는 속성 래퍼
class DataModel: ObservableObject {
@Published var name = "Some Name"
@Published var isEnabled = false
}
struct MyView: View {
@StateObject private var model = DataModel() // Create the state object.
var body: some View {
Text(model.name) // Updates when the data model changes.
MySubView()
.environmentObject(model)
}
}
name
, isEnabled
가 변경되면 뷰가 업데이트publisher가 있는 타입을 나타내는 프로토콜
변경 시 publisher를 보낼 프로퍼티를 표시
$
오퍼레이터를 통해 publisher에 접근ObservableObject를 구독하고 ObservableObject가 변경될 때마다 뷰를 무효화하는 속성 래퍼
struct MyView: View {
@StateObject private var model = DataModel()
var body: some View {
Text(model.name)
MySubView(model: model)
}
}
struct MySubView: View {
@ObservedObject var model: DataModel
var body: some View {
Toggle("Enabled", isOn: $model.isEnabled)
}
}
ObservableObject인 DataModel 타입을 상위 뷰(MyView)에서 주입받아 사용
부모 또는 조상 뷰에서 제공하는 ObservableObject에 대한 속성 래퍼
environmentObject(_:)
수정자를 호출하여 설정하면 모든 뷰에서 사용 가능struct MyApp: App {
@StateObject private var model = DataModel()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(model)
}
}
}
struct MyView: View {
@EnvironmentObeject private var model: DataModel
var body: some View {
Text(model.name)
MySubView(model: model)
}
}