【SwiftUI】Property Wrapper @Observedobjectと@StateObject

iOS14で追加になった、@StateObjectについてみていきます。親Viewが状態が変化され、再描画されると状態が破棄される@ObservedObjectとは異なり、@StateObjectは状態は保持されます。下記簡単なサンプルを掲載します。

1. 例について

親VIewに乱数のテキストと乱数の更新する青いボタンがあり、子のViewにそれぞれHStackで更新ボタンと更新ボタンを押下するとカウントアップするViewを配置します。下のスクリーンショットは、子のViewに緑と赤の更新ボタンを配置しております。青いボタンのあるViewには、@ObservedObjectが定義されており、赤いViewには@StateObject定義されてます。 親Viewにある乱数の更新ボタンを押下すると親Viewが更新され、その時に、子のViewがどうなるかを見るサンプルです。

2. SampleView,SampleView2を更新

青と赤の更新ボタンを押下してそれぞれ、4までカウントアップします。

3. 親Viewを更新

乱数の更新ボタンを押下すると親Viewが更新され、乱数の表示が変わります。この時、子Viewのそれぞれは下図のように変わります。@StateObjectを定義した赤いボタンを含むViewは0にならずリセットされませんでした。

4. サンプルコード

上記の例で利用したコードです
import SwiftUI
struct ContentView: View {
@State var title = 0
var body: some View {
VStack(spacing: 0.0) {
Text("乱数:\(self.title)").padding(.bottom,10.0)
Button("乱数の更新\n(Viewの更新)") {
self.title = Int.random(in: 0...50)
}.modifier(MyButton(color: .blue))
Spacer().frame(height: 100.0)
SampleView1().padding(.bottom,20.0)
SampleView2()
}
}
}
struct SampleView1: View {
@ObservedObject var model = ViewModel()
var body: some View {
HStack(spacing:20.0) {
Text("SamepeView1 count: \(self.model.count)")
Button("更新") {
self.model.count += 1
}.modifier(MyButton(color: .green))
}
}
}
struct SampleView2: View {
@StateObject var model = ViewModel()
var body: some View {
HStack(spacing:20.0) {
Text("SamepeView2 count: \(self.model.count)")
Button("更新") {
self.model.count += 1
}.modifier(MyButton(color: .red))
}
}
}
class ViewModel: ObservableObject {
@Published var count = 0
}
struct MyButton: ViewModifier {
let color: Color
func body(content: Content) -> some View {
content
.foregroundColor(.white)
.padding()
.background(color)
.clipShape(RoundedRectangle(cornerRadius: 10))
}
}

このブログの人気の投稿

アプリアイコンの素材探し

【SwiftUI】グラスモーフィズムを試してみました

【SwiftUI】LazyVGridについて