SWIFTUI 初歩の初歩

SWIFTを触るのも初めてで、web上の情報とか見ながら始めました。

SWIFTUI 最初はこんなコードが現れる

 

import SwiftUI

 

struct

ContentView: View {

    var body: some View {

        Text("Hello, World!")

    }

}

 

struct ContentView_Previews: PreviewProvider {

    static var previews: some View {

        ContentView()

    }

}

 

画面に Hello, World! と表示するだけのコード。

ここからいじり出すのだけれど、じゃあもう1行テキストを追加ってことで、

struct

ContentView: View {

    var body: some View {

            Text("Hello, World!")

             Text("ヤッホー")

    }

}

ってやると、いきなりエラー。

View{} の中には1つだけしか書けないらしい。

それじゃあんまり困るので、この2つのテキストをVStack{}というので囲んでやると良いらしい。

struct

ContentView: View {

    var body: some View {

       VStack{

    Text("Hello, World!")

             Text("ヤッホー")

           }

    }

}

縦に並べるのがVStack、横に並べるのがHStack、重ねるのがZStack。

これで囲むと、囲まれた1つのかたまりとみなされるみたい。

それじゃあ、幾つでも囲めるかっていうとそうでもなく、最大10個らしい。

でも、囲んだものは1個とみなされるので、

VStack{

    VStack{

        VStack{

        }

    }

    VStack{

    }

}

みたいに入れ子にしてあげればいくらでも追加できる。

それから、別のVIEW(子VIEW)を作って、それを表示する事もできる。

struct view3: View {        // 親

    var body: some View {

        VStack {

            view4()

            view5()

        }

    }

}

 

struct  view4: View {        // 子

    var body: some View {

    Text("Hello, World!")

    }

}

 

struct  view5: View {             //  子

    var body: some View {

    Text("ヤッホー")

    }

}

つまり、子VIEWで部品を作っておいて、親VIEWでをれを組み合わせることができる。

ここで問題になるのが、子VIEWに表示させる文字列をどうやって変えるかってこと。

プログラムなんだから、いつも同じ文字が表示されているだけだったらつまらない。

struct view3: View {

    var body: some View {

        VStack {

            view4(txt: "ハロー")

            view4(txt: "Hello")

        }

    }

}

 

struct  view4: View {

    @State var txt: String

    var body: some View {

    Text("\(txt)")

    }

}

子VIEWで 

@State var txt: String

として、文字列型の変数txtを宣言してやると、親VIEWから呼び出すときに、このtxtに入る文字列を指定できる。

子VIEWの

Text("\(txt)")

の\ はoption+¥ で入力する。

 

じゃあ、親VIEWで指定した "ハロー" も変数で指定したいよね。

struct view3: View {

    var text: String = "ハロー"

    var body: some View {

        VStack {

            view4(txt: text)

            view4(txt: "Hello")

        }

    }

}

変数使ってるけど、その文字列、プログラムでどうやって切り替えるの?

例えば、ボタンを押した時に表示が切り替わるようにするには?

 

struct view3: View {

    @State var text: String = "ハロー"

    var body: some View {

        VStack {

            Button(action: {

                self.text = "こんにちは"

            }){ Text("ボタン")}

            view4(txt: text)

            view4(txt: "Hello")

            Text(text)

        }

    }

}

@State をつけると、変数の値が変化したときに、VIEWに反映されるらしい・・・が、

このView3のtextは確かに変化しているのだけれど、子VIEW(view4)の表示は変わらない。

だめダァ〜。

struct view3: View {

    @State var text: String = "ハロー"

    var body: some View {

        VStack {

            Button(action: {

                self.text = "こんにちは"

            }){ Text("ボタン")}

            view4(txt: $text)

//            view4(txt: "Hello")

            Text(text)

        }

    }

}

struct  view4: View {

    @Binding var txt: String

    var body: some View {

    Text("\(txt)")

    }

}

子VIEW(view4)の変数を@Binding で宣言してやると、子VIEWの値も書き換わりました。

でも、文字列定数は受け付けてもらえないみたい。

まあ、それはもう一つ変数を定義して、文字列定数を割り当てておけば良いか。

struct view3: View {

    @State var text: String = "ハロー"

    @State var textconst: String = "Hello"

    var body: some View {

        VStack {

            Button(action: {

                self.text = "こんにちは"

            }){ Text("ボタン")}

            view4(txt: $text)

            view4(txt: $textconst)

            Text(text)

        }

    }

}

これでなんとかVIEW間で値のやり取りができるようになったけれど、1個ずつ変数を定義するの?

ObservedObject というのを使うと、classで定義したオブジェクトを渡せるらしい。

でも、親から子への一方通行。

EnvironmentObject というのを使うと双方向で値を渡せるらしい。

で、プログラムって入力に対していろいろな処理をすると思っているんだけれど、それ、ボタンのアクションに全部書いていく事になるのかな?

classっていうのを勉強する必要がありそう。