自分は開発する中である程度文法を覚えたいという習性があります。
プログラム書いていても、引数に何を入れないといけなかったんだっけ?
どういう型のものを入れないといけないんだっけ?
と思い出すためにいつも色々検索してヘルプを見て学んでの繰り返しです。
なので、ある程度はメソッドや使い方については覚えておきたいですよね!
何回も調べるのもいいですが、その調べる時間もかかり勿体無いですよね。
その中でも自分が覚えれない、以下の4つについてまとめておこうと思います。
- Animation
- Gradient
- Gesture
- GeometryReader
Animation
animationとは、あるViewに対して動きをつけるものです。
あるViewに対して動きをつけるということなので、そのViewに対してanimationモディファイアがあります。
さらに、View全体に動きをつけたりするためのものとして、withAnimationというものもあったりします。
animationモディファイア
animationモディファイアは
1つ前のモディファイアの動きに対して、animationモディファイアを実行して、
すでに1つ前で動きが定義されているので、それに対してanimationモディファイアではただ速度。どのくらいの速さでその動きを変化させるかを定義するだけです。なので引数にもそれだけを指定します。
なので、scaleEffect()のような拡大させるモディファイアなどに対して、animationモディファイアを指定することで、
その拡大要素に対してアニメーションを付けることができます。
Text("aaa") .scaleEffect() .animation(Animation.linear())
withAnimation
そしてwithAnimationは、
Animationと共にということで、Viewに対して何かの変化をanimationで設定するというもの。
view全体(複数のView)の状態変化なので、例えば@Stateなどのものに変化があるのと同じように変化を加えるということです。
そして状態変化をどのくらいの速度で変化させる?という情報が必要になるので、
引数にはanimationモディファイアと同じ速度を指定して、そしてどういう処理をするかなので処理内容の関数をクロージャーで引数に指定します。
withAnimationは、animationモディファイアと違って処理を書くことができるので、
@State変数など、状態変数を用いて処理を記載し、View全体の再構築をさせながら複数のViewのアニメーションを施したりすることができます。
Button( action:{ withAnimation( animation: Animation.linear(), body: { } ) }, label:{ Text("button") } )
要はanimationモディファイアでは、すでに動きが定義されているものに対してanimationモディファイアを指定するので、残りの情報としてどのくらいの速さで動かすかを指定する。(easeInとか)
withAnimationは、インスタンスを生み出した瞬間にanimation実行ですが、インスタンスで前に対して指定するモディファイアとは違うので、
どういう処理をするか、そしてその処理をどのくらいの速さで動かすかの2つを指定する必要がある。
メソッド | 説明 |
---|---|
linear() | |
easeIn() | 最初が遅く、だんだんと最後に速くなる |
easeOut() | |
easeInOut() | 最初遅く始まっていき、真ん中で速度ピークとなって、最後にだんだん遅くなる |
上記は1回に対してどういう速度で変化させるかを定義したものです。
何回も繰り返し処理したい場合もあります。
そういう場合は以下のようにrepeat(リピート)を指定します。
上記のメソッドは実行結果はAnimationインスタンスを返すため、
メソッドチェーンのように、上記メソッドに対して、
repeatCount()を実行できます。
Gradient
グラデーションに必要なものとしては当然、複数の色とどこから色を変えていくか
さらに色の変化の加え方。線形なのか円形なのか?
gradientには使用する色の指定。
これは共通で、グラデーション系は必ず指定します。
線形にグラデーションしたい場合は、linearGradient( )
そして線形となるとどこから色を変えていくか、そしてどこまで色を変えるかを指定しないとダメなので、
linearGradient( gradient: 色指定、startPoint: 開始点、endPoint: 終了点 )
そして円形となると、どこを基点として円状に色をグラデーションするかなので、
AnglerGradient( gradient: 色指定、center: どこ?、angle: どの角度で色変える?)
Gesture
ジェスチャーも結構イメージは簡単です。
ジェスチャーの始まり方としては、タップやスワイプなど一回画面を触らないと発生しません。
なので、
まず待機状態として、
インスタンスを生成します。
そしてそれに対して挙動を定義することで、ジェスチャーの設定が可能です。
インスタンスを生成することで、ジェスチャー待機状態にするイメージですね。
TapGesture
LongPressGesture
DragGesture
MagnificationGesture
RotationGesture
これらのジェスチャーは触ったらドラッグを生成します。
画面に触るとそのジェスチャーを生成します。
DragGestureなら、まずタップしてちょっと動かすことでDragGestureを生成して処理をします。
TapGestureの場合は、1回タップした場合、2回タップした場合と設定して生成します。
2回タップした場合に生成して処理をしたい場合は、
DragGesture() .onChanged{ value in } // 動かしている間(動かしている間は自動的に値を取得する。Dragの現在位置を引数に渡される) .onEnded { value in } // ドラッグが終わった瞬間
valueは動かしている間の情報で、自動的に連携される。
valueには何が入るかは後で。
TapGesture(count: 2) // 2回タップしたら生成して処理開始します .onEnded{} // 中間はないのでendedのみ。そしてDragのようにドラッグしてる時、そのドラッグ量などはないので、valueなどの情報は渡されない
LongPressGesture(minimumDuration: 3) // Longって言ってもどのくらいタップし続けたらインスタンスを作成するかは、minimunDurationで設定する。3秒 .update{} .onEnded{}
↑ 当然これらは、Gestureプロトコルを返すので、
変数でlet gesture: some gesture{
}
の中で記載してもいいし、
.onTapGesture()
の中に記載してもOK
そして基本的にこのジェスチャー処理は各Viewに対して定義する。
要は画像を動かしたいなどなら、その画像にgestureモディファイアを定義して、
gestureモディファイアはGestureプロトコルを返さないといけないので、
上のものを記載します。
letでstructのプロパティで定義して、その変数をgestureモディファイアに定義するのでもいいし、
gestureモディファイアの中に直に上のインスタンスを作って処理書いてもいいし。
当然動かしている時にImageなども動くことになるので、
動いている時にDragに関してはvalueを自動的に受け取ることができる。
Geometry
Geometryでは、親のViewの大きさをしれます。
これも引数に自動的に変わりうる親のViewサイズを自動的に受け取ります。
GeometryReader(){ GeometryProxy in }
Geometryは親Viewのサイズを取得するので、普通にViewのように宣言できる。
GeometryReaderはViewプロトコルに準拠しています。
GeometryReader()というインスタンスを生成することで、
このインスタンスが自動的にViewの大きさを取得します。
そうすると、その大きさの情報を使用できるように、GeometryProxyに渡してその中で処理を行うことができます。
もちろんGeometryProxyではなく、他の変数名で構いません。
GeometryReaderのインスタンスを生成したことによって受け取った情報の中には代表的なものとしては、
GeometryProxy.size.width
GeometryProxy.size.height
があります。
要は、親Viewのwidthとheightです。