多くのプログラムの機能として存在する引数を付けてサブプロをCallするときパラメータの書き方は、どうするっていう疑問です。
最近、SwiftUIを勉強しています。
Viewがひとつだけのものの作り方しか知らなかったのですが、最近、2つ以上のビューをひとつのプログラムで制御する練習問題に、ぶち当たりました。(笑)
そうすると、どうしても、ある画面で入力した変数の内容を、もうひとつ画面で参照する必要が出てくるため
ビュー間の、値の受け渡しは、どうやるの?ってことが重要解決問題になりました。
以下ソースが完成形です。
import SwiftUI
// View間で、受け渡しをしたい値を保持するクラスの定義
class Data_class : ObservableObject {
@Published var koumokuA = "ABC" //初期値をいれないと面倒なのでなにか入れる
}
// 親ビュー
struct ContentView: View {
// クラスからインスタンスを生成
@ObservedObject var instance_Name = Data_class()
var body: some View {
if (instance_Name.koumokuA == "ABC") {
view_A(instance_ko1:instance_Name) // 最初は必ずここを通るように作る
} else {
view_B(instance_ko2:instance_Name)
}
}
}
// 子ビューA
struct view_A: View {
// インスタンスを生成するが、親から指定されたインスタンス名と合致して値が渡る
@ObservedObject var instance_ko1 = Data_class()
var body: some View {
VStack {
Text("項目Aの値は、\(instance_ko1.koumokuA)")
Button("ボタンを押すと項目の値をZZZにします。"){instance_ko1.koumokuA = "ZZZ"}
// ボタンが押されたら 監視下の値を変化させ親ビューif文のelse側を表示させる。
}
}
}
// 子ビューB
struct view_B: View {
// インスタンスを生成するが、親から指定されたインスタンス名と合致して値が渡る
@ObservedObject var instance_ko2 = Data_class() // インスタンスを生成
var body: some View {
Text("項目Aの値は、\(instance_ko2.koumokuA)")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct から struct への値渡しの方法と言っても良いのですが
SwiftUIのビューは、必ず struct でできているらしいので、structから、struct への引数渡し方法 と題名を変更しても良いのですが。ま、とにかく調べに調べました。見つけたサンプルが皆さん、ObservableObject, ObservedObject(似てますよね。この2つ、一見して同じかと勘違いしました),Environment, EnvironmentObjects等々なにか特殊なものを使うと書いているんですね。
本題とは、少しずれるのですが
サンプルは、結局ObservableObject と ObservedObjectを使用しました。なので、このサンプルではインスタンス(名)を渡す例ということになります。
上記サンプルの説明を、しますね。
①クラスを用意(データをいれるための変数も書きます。)※これは本題とは少しずれてはいますが
ポイントは、クラス名の後に ObservableObject と書くことです。それと変数名の前には、@Published と書くことです。これにより、また余談ですがSwiftUIの監視下に入り、値が変化すると、Viewが再描画されるとのことです。
// View間で、受け渡しをしたい値を保持するクラスの定義
class Data_class : ObservableObject {
@Published var koumokuA = "ABC" //初期値をいれないと面倒なのでなにか入れる
}
②親ビューにて、上記クラスを使用してインスタンスを生成します。これが元ですね。
インスタンス名は、instance_Name としました。
// クラスからインスタンスを生成
@ObservedObject var instance_Name = Data_class()
③そして、これがViewからViewへの値の渡し方
view_A(instance_ko1:instance_Name) // 最初は必ずここを通る...
ビュー名(callする子側の変数名:callする親側の変数名)
と書くのが正解のようです。
端切れの悪い書き方で、すみません。正解が出ているサイトを最後まで見つけられませんでしが、これが正解だと思います。
ビュー名(callする子側の変数名:callする親側の変数名) と書くのが正解のようです。
今回のサンプルは、クラス(というかインスタンス)を渡しているので、インスタンスは参照型らしく、これにより、渡したい値を子側に渡すだけではなく子側で値を変更しても、その変更後の値が親側で受け取れるということのです。試しました。そうでした。