兩種方法可以做動畫:
Shape
ViewModifier
withAnimation { ... }
??
ViewModifier 是什麼東西?
這邊的 AspectModifier 是一個 ViewModifier,view 套用 ViewModifier 後再被送出去
而 AspectModifier 這個 ViewModifier 需要 conform Modifier
protocol
only job is to create a new View based on the thing passed to it.
ViewModifier
跟一般的 View
程式碼看起來非常像,差異是
ViewModifier 做的事需要把 View 丟進去,然後他會處理後再丟出來
先丟進去 | 再丟出來 |
---|---|
自製 ViewModifier - Cardify
讓「卡片」這個 View 透過傳入的 isFaceUp 決定是正面(卡片內容)或反面(色塊)
把卡片內容替換成任意 View 也有相同的卡片樣式
ViewModifier are the primary "change agent" in the UI. A change to a ViewModifier's arguments has to happen after the View is initially put in the UI. In other words, only changes in a ViewModifier's arguments since it joined the UI are animated. Not all ViewModifier arguments are animatable (e.g. .font's are not), but most are.
.animation(.linear)
withAnimation(.linear) { ... }
The .animation modifier does not work how you might think on a container. A container just propagates the .animation modifier to all the Views it contains. In other words, .animation does not work on like .padding, it works mpre like .font.
設定 animation 的一些細節: duration, delay, repeat, linear, easeInOut…
Transition sprcify how to animation the arrival/departure of Views.
Only works for Views that are inside CTAAOS(Containers That Are Already On-Screen)
Under the covers, a tranisiton is nothing more than a pair of ViewModifiers. One of the modifiers is the "before" modification of the View that's on the move. The other modifier is the "after" modification if the View that's on the move. Thus a transition is just a version of a "changes in arguments to ViewModifiers" animation.
An asymmetric transition has 2 pairs of ViewModifiers. One pair for when the View appears (insertion). And another pair for when the View disappears (removal). Example: a View fades in when it appears, but then flies across the screen then it disappears.
Mostly we use "pre-canned" transitios (opacity, scaling, moving across the screen). They are static vars/funcs on the AnyTransition
struct.
all the transition API is "type erased"
.matchedGeometryEffect(id: ID, in: namespace)
all actual animation happens in shapes and ViewModifiers.
(even transition and matchedGeometryEffects are just "paired ViewModifiers")
so how do they actually do their animation?
the communication with the animation system happens (both ways) with a single var. This var is the only thing in the Animatable protocol. Shape and ViewModifier that want to be animatable must implement this protocol.
寫這樣的話,isMatched 改變後的動畫會瞬間就完成,所以看不到過程。
多加一行表示我們想要 implicit animation。
但有問題出現了
點了的第二張卡片沒有旋轉動畫 | 裝置旋轉後會有奇怪的位移動畫 |
---|---|
因為 .font()
這個 ViewModifier 不是 animatable
所以我們用另一種方式來達到調整字體大小的目的 .scaleEffect()
.animation(…) 放置的位置很重要,他會套用到該行以前的 View
所以應該要寫成
而不是
animation 只會被用在被改變的圖