Tag: SwiftUI/PropertyWrapper
関連ページ†
参考情報†
Property Wrapperの種類†
- @State、@Binding、@StateObject、@ObservedObjectなどデータを管理するためのProperty Wrapperがたくさん存在する
@State†
@Binding†
- データが値型。データの更新あり。データの発生源は外部。
struct ParentView: View {
@State private var counter = 0
var body: some View {
ChildView(counter: $counter)
.frame(width: .infinity)
}
}
struct ChildView: View {
@Binding var counter: Int
var body: some View {
Button(action: {
counter += 1
}, label: {
Text("\(counter)")
.font(.title)
})
.border(Color.red)
}
}
@Environment†
ObservableObjectプロトコル†
@StateObject†
@ObservedObject†
- データが他参照のデータオブジェクト。データの発生源が外部。
fileprivate
struct ParentView: View {
@StateObject private var dataSource = DataSource()
var body: some View {
ChildView(dataSource: dataSource)
}
}
fileprivate
struct ChildView: View {
@ObservedObject var dataSource: DataSource
var body: some View {
VStack {
Button("increment counter") {
dataSource.counter += 1
}
Text("count: \(dataSource.counter)")
}
}
}
}
}
** @StateObjectと@ObservedObjectの違い
-以下のサンプルを考える。
#pre{{
struct StateObjectCounterView: View {
@StateObject private var dataSource = DataSource()
var body: some View {
VStack {
Button("increment counter") {
dataSource.counter += 1
}
Text("StateObject count: \(dataSource.counter)")
.font(.title)
}
}
}
struct ObservedObjcetCounterView: View {
@ObservedObject private var dataSource = DataSource()
var body: some View {
VStack {
Button("increment counter") {
dataSource.counter += 1
}
Text("ObservedObject count: \(dataSource.counter)")
.font(.title)
}
}
}
struct SwitchColorView: View {
@State private var isDanger: Bool = false
var body: some View {
VStack {
Button("Change the Color") {
isDanger.toggle()
}
if isDanger {
Circle().foregroundColor(.red)
.frame(width: 200, height: 200)
} else {
Circle().foregroundColor(.green)
.frame(width: 200, height: 200)
}
StateObjectCounterView()
ObservedObjcetCounterView()
Spacer()
}
}
}
- StateObjectとObservedObjectをカウントアップした後、「Change the Color」で色を変更すると、StateObjectのカウントは維持されるが、ObservedObjectはリセットされる。
- @StateObjectはViewを表示してから非表示まで。@ObservedObjectはbodyが更新されるまでのため。
- これを避けるためには、@ObservedObjectには親Viewからわたす。
@EnvironmentObject†