Last active
September 6, 2021 09:21
-
-
Save yimajo/d34a6a33c7369512bd0d67b058187846 to your computer and use it in GitHub Desktop.
SwiftUIでBindingは参照元の値を変更できるが、Stateは参照元の値を変更できないサンプル。Playgroundで動作する。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import PlaygroundSupport | |
import SwiftUI | |
import Combine | |
class ObservableObject1: ObservableObject { | |
@Published var name: String = "src" | |
} | |
struct ContentView1: View { | |
@ObservedObject private var object = ObservableObject1() | |
var body: some View { | |
VStack { | |
VStack { | |
Text("Change from: \(object.name)") | |
} | |
VStack { | |
Text("ContentView @ObservableObject") | |
.font(.headline) | |
Button(action: { | |
self.object.name = "ContentView1" | |
}) { | |
Text("ContentView: Button \(object.name)") | |
} | |
} | |
.padding(20) | |
VStack { | |
Text("SubViewO @ObservedObject") | |
.font(.headline) | |
SubViewO(object: object) | |
} | |
.padding(20) | |
VStack { | |
Text("SubViewB @Binding") | |
.font(.headline) | |
SubViewB(name: self.$object.name) | |
} | |
.padding(20) | |
VStack { | |
Text("SubViewS @State") | |
.font(.headline) | |
SubViewS(name: self.object.name) | |
} | |
} | |
} | |
} | |
struct SubViewO: View { | |
@ObservedObject private(set) var object: ObservableObject1 | |
var body: some View { | |
VStack { | |
Button(action: { | |
self.object.name = "SubViewO!!" | |
}) { | |
Text("SubViewO: Button \(object.name)") | |
} | |
} | |
} | |
} | |
struct SubViewB: View { | |
// Viewがデータに対してBindingする。 | |
// 双方向(two-way)のBindingとなり、このViewで変更されたら参照元も変更する。 | |
// https://developer.apple.com/documentation/swiftui/binding | |
@Binding private(set) var name: String | |
var body: some View { | |
VStack { | |
Button(action: { | |
// 参照元のnameも変更できる | |
// 参照元はObservableObjectなのでそのnameも変わる | |
self.name = "SubViewB!!" | |
}) { | |
Text("SubViewB: Button \(self.name)") | |
} | |
} | |
} | |
} | |
struct SubViewS: View { | |
// Viewがデータにconnectされる。 | |
// 参照元からは初期値のみ取得し参照元の監視はしていない。 | |
// Viewはデータを保持し、View内でデータが更新されるとViewを更新する。 | |
// https://developer.apple.com/documentation/swiftui/state | |
// 外側から変更されるべきではないのでprivateに。 | |
// privateにするとinit書かないといけないの面倒なのでprivate(set)にした。 | |
@State private(set) var name: String | |
var body: some View { | |
VStack { | |
Button(action: { | |
// 自分のStateを変えるが参照元は変わらない | |
self.name = "SubviewS!!" | |
}) { | |
Text("SubViewS: Button \(self.name)") | |
} | |
.padding(10) | |
SubViewS_B(name: self.$name) | |
} | |
} | |
} | |
struct SubViewS_B: View { | |
@Binding private(set) var name: String | |
var body: some View { | |
VStack { | |
Text("SubViewS_B @State-@Bind") | |
.font(.headline) | |
Button(action: { | |
// 参照元ののnameも変更する | |
// 参照元がStateならそれ以上(ObservableObjectの値)は変わらない | |
self.name = "SubviewS_B!!" | |
}) { | |
Text("SubViewS_B: Button \(self.name)") | |
} | |
} | |
} | |
} | |
PlaygroundPage.current.liveView = UIHostingController(rootView: ContentView1()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment