//tips
//Swift背景色の設定
背景色をつけたい場合はコードの一番上にZStackを設けて、
ZStack{
Color()
.edgesIgnoringSafeArea(.all) //上下の余白を超えて表示する
・・・
とすれば良い。
色の中身は、Color(red: , green: , blue: )というふうに赤緑青を0から1の間で記載していく。ただ、どのような色になるのか分かりづらいので、()内にcolorと記入すると、Color Literalを選択できるようになるので、それを押すと、配色パレットが出てくるのでこれで色を指定することもできる。
//image 画像の反映
事前にプレビューに反映させたい画像をAssets.xcassetsに取り込んでおき、その画像の名前をImage(“ ”)の中に入れることで画像データを反映することができる。
また、frame()メソッドで画像の大きさを調整することができるが、frameで指定されるwidthとheightの数値はポイントという単位(xcodeのプレビュー画面のサイズを表す単位)で表される。
UI部品の配置は、全てポイントで指定することになるが、これは実際の端末毎の見え方を示しているわけではなく、プレビューの中での相対的な位置関係を表す。
実際の端末での表示はピクセルで表される。
例えば、iPhone 11 Pro Maxでのプレビューは414×896ポイントの大きさで表示されるが、実機では1242×2688ピクセルとして描画される。その分だけ違った表示のされ方をすることを覚えておく。
//swiftでのアニメーション
Swiftのアニメーションは装飾部品により表現される。
前回の英単語カードアプリで言うと、
Image("card")
.resizable()
.frame(width: 300.0, height: 133.0)
.shadow(radius: 3)
.rotation3DEffect(
.degrees(isJapanese ? 0 : 180),
axis: /*@START_MENU_TOKEN@*/(x: 0.0, y: 1.0, z: 0.0)/*@END_MENU_TOKEN@*/)
.animation(.spring())
.onTapGesture{self.isJapanese.toggle()
}
rotation3DEffectと.animation(.spring())が該当する。
分かりやすい.animation(.spring())から見ていくと、()の引数にアニメーションの種類を指定することでUI部品に動きを与える。
string():バネのように変化
Linear:一定速度で変化
easeIn:最初ゆっくり変化
などがある。
rotation3DEffectはUI部品を三次元で回転させる。第一引数は回転角度、第二引数は回転軸を指定する。
.rotation3DEffect(
.degrees(isJapanese ? 0 : 180),
axis:(x: 0.0, y: 1.0, z: 0.0))
回転角度の指定では、degree()メソッドを使い、isJapaneseの値が真の場合は0,偽の場合は180が引数になる。
つまり、falseの時にカードの裏表がひっくり返るエフェクトが発生する。
第二引数の回転軸指定では、0を指定された軸は関与せず、ゼロ以外を指定した軸を中心にdegree()メソッドが発生することになる。
今回はy軸を起点にUI部品が回転する。
//swiftのクリック処理
Swiftのクリック処理はUI部品への装飾部分によって行われ、その装飾した部品をタップした際に処理が行われる。
Image画像に下記の装飾がなされており、
.onTapGesture{self.isJapanese.toggle()}
画像タップを行うと、self.isJapanese.toggle()が実行され、isJapaneseの値をtrue or falseに切り替える処理を行う。
このisJapanese値の切り替えから連動して、それを引数にもつ、先の.rotation3DEffectアニメーションが発生する。
OnTapGestureのようにユーザーがUI部品を操作できるものをジェスチャーといい、
On Long Press Gesture:長押し
Drag Gesture:ドラッグ
Rotation Gesture:2本指で回転させるように行うドラッグ
などの種類がある。
//複数のUI部品をまとめる
複数のUI部品に同じ装飾を指定したい場合、Groupによりまとめると便利である。
Group{
Button(action:{self.isJapanese.toggle()
}) {
Image(systemName:"arrow.2.circlepath")
Text("裏返す")
}
Button(action: {
self.isJapanese = true
self.japanese = self.cards.randomElement()!.key
}) {
Image(systemName:"forward.fill")
Text("次へ")
}
}.padding()
.foregroundColor(.white)
.background(Color(red:0.86, green:0.45, blue: 0.03))
.cornerRadius(10)
}
上記のように、「裏返す」と「次へ」のボタンを同じ装飾にしたい場合に用いられる。
装飾部分はどこかと言うと、一番最後に付け加えられた
.padding()
.foregroundColor(.white)
.background(Color(red:0.86, green:0.45, blue: 0.03))
.cornerRadius(10)
をさす。
//ボタン内部にアイコン画像とテキストを両方記載する
一つのボタン内部にアイコン画像とテキストを表示する。これは案外簡単にできるので覚えておいて損はない。
Button(action:{self.isJapanese.toggle()
}) {
Image(systemName:"arrow.2.circlepath")
Text("裏返す")
}
Button構造体の第二引数には複数のUI部品を指定することができ、この際にアイコン画像を追加することでボタン上に複数の部品を追加することができる。
//ContentView構造体の理解
Codeの最初にいつも書かれている下記について理解する。
struct ContentView: View {
var body: some View {
まずstruct ContentView: Viewは、ContentView構造体が Viewプロトコルに基づくことを示している。
プロトコルとは一種の約束事で、Viewプロトコルは、テキスト、ボタン、スライダーなどのswiftUIフレームワークにあるUI部品に対する約束事である。
この約束事が守られている構造体だけが、iphone画面に表示することができ、:viewの部分を消したり、自作の構造体であったり、MKMapViewクラスなどは、シンプルに表示することはできない。
そのため、Viewプロトコルに批准していない構造体は表示させるためには、うまく橋渡しをしなければならない。
言い換えると、一般的に「SwiftUIフレームワークの中のUI部品はViewプロトコルに批准した構造体である」と言える。
そして、このViewプロトコルに批准する上で書かなければならない約束事として、bodyプロパティというものがあり、
var body: some View {
に該当する。
bodyプロパティの戻り値の型は「some view」で、これはViewプロパティに批准した戻り値でなければならないことを指す。
例えば、Textがbodyの中に組み込まれている場合、これはText構造体がViewプロトコルに批准しているため、bodyの戻り値に指定できる。
基本的に、SwiftUIフレームワークのUI部品はViewプロトコルに批准済みであるのでそこまで問題にならない。
このsomeの部分は便利で、Swift側が変数の方を自動的に推測してくれるという機能を持つ。
他の言語では
String hello = “こんにちは”
などと変数の型を自分で書かなければいけないところをSwiftでは、先にvar body:some view{としておくことで
var hello = “こんにちは”
などとvarを使い、簡潔に書くことができる。