Viewオブジェクトの表示・非表示の切り替え時のアニメーションを定義するtransitionモディファイアは、animationとセットで使用する必要があります。
しかしながら、animationの指定方法によってtransitionが正しく機能しないケースがあるようです。
本記事では、transitionが機能しないケースを紹介します。
環境
この記事の情報は次のバージョンで動作確認しています。
【Swift】5.2.4
【iOS】13.5
【macOS】Catalina バージョン 10.15.4
ケース1:Viewに暗黙的なanimationを指定
Viewに対して暗黙的なアニメーションを指定したケースでは、一部のtransition効果が機能しません。
次のコードを実行して、「トランジション」ボタンをクリックすると、青い円がアニメーション効果を伴って表示・非表示が切り替わります。
しかし、transitionのオプションを.scaleまたは.opacityに変更すると、アニメーションが機能しません。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21  | 
						struct ContentView: View {     @State private var flag = true     var body: some View {         VStack {             Button("トランジション") {                 self.flag.toggle()             }             if flag {                 Circle()                     .fill(Color.blue)                     .frame(width: 100, height: 100)                     .animation(.default)    // 暗黙的なアニメーションの指定                     .transition(.slide)     // トランジションの適用             }             Spacer()         }     } }  | 
					
一部のサイトや書籍では「Appleはtransitionを明示的なanimationと一緒にしか使用できないように変更した」との情報もあるので、このケースでは機能しない方が正しい仕様なのかもしれません。
ケース2:AnyTransitionインスタンスにanimation適用
Appleの公式リファレンスマニュアルを見ると、AnyTransitionのインスタンスに、直接animationモディファイアを使用できると書いてあります。
次のコードを実行すると確かにそれは機能するのですが、transitionのオプションを.slideに変更すると機能しなくなります。
このケースでは、先程のケースとは逆で、.scaleまたは.opacity以外のオプションがなぜか機能しなくなるようです。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20  | 
						struct ContentView: View {     @State private var flag = true     var body: some View {         VStack {             Button("トランジション") {                 self.flag.toggle()             }             if flag {                 Circle()                     .fill(Color.blue)                     .frame(width: 100, height: 100)                     .transition(AnyTransition.scale.animation(.default))     // トランジションの適用             }             Spacer()         }     } }   | 
					
回避策
transitionを使用する場合は、次のコードように明示的なアニメーション指定をすると良いです。
プロパティに対する明示的なアニメーション指定の場合は、確認した限りすべてのtransitionオプションが正常に機能します。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22  | 
						struct ContentView: View {     @State private var flag = true     var body: some View {         VStack {             Button("トランジション") {                 withAnimation() {          // 明示的なアニメーション指定                     self.flag.toggle()                 }             }             if flag {                 Circle()                     .fill(Color.blue)                     .frame(width: 100, height: 100)                     .transition(.scale)     // トランジションの適用             }             Spacer()         }     } }  | 
					
あわせて読みたい記事


  
  
  
  
