78435


# 質問

animationモディファイアとwithAnimationの違いはなんですか？  
理解しようと思って、下記のサンプルを書いてみたのですが、同様の動きをする場合としない場合があることはわかったのですが、どのようなときに違いが生まれるのか等、イマイチわかりませんでした。

# 書いてみたサンプル

## animationモディファイアとwithAnimation、どちらで書いてもアニメーションする例

### animationモディファイア版

[code]

    import SwiftUI
    
    struct ContentView: View {
      @State private var scale: CGFloat = 1.0
    
      var body: some View {
        VStack {
          Rectangle().frame(
            width: 100,
            height: 100
          )
          .scaleEffect(
            scale
          )
          .animation(
            .default
          )
          Button(
            "scale +",
            action: {
              scale += 0.5
            }
          )
        }
      }
    }
    
[/code]

### withAnimation版

[code]

    import SwiftUI
    
    struct ContentView: View {
      @State private var scale: CGFloat = 1.0
    
      var body: some View {
        VStack {
          Rectangle().frame(
            width: 100,
            height: 100
          )
          .scaleEffect(
            scale
          )
          Button(
            "scale +",
            action: {
              withAnimation {
                scale += 0.5
              }
            }
          )
        }
      }
    }
    
[/code]

## withAnimationの場合のみアニメーションする例

### animationモディファイア版

[code]

    import SwiftUI
    
    struct ContentView: View {
      @State var flag = false
    
      var body: some View {
        ZStack {
          if flag {
            FirstView(
              flag: $flag
            )
          } else {
            SecondView(
              flag: $flag
            )
          }
        }
      }
    }
    
    struct FirstView: View {
      @Binding var flag: Bool
    
      var body: some View {
        ZStack {
          Color.green.ignoresSafeArea()
          Button(
            "Button",
            action: {
              flag.toggle()
            }
          )
        }
        .transition(.opacity)
        .animation(.default)
      }
    }
    
    struct SecondView: View {
      @Binding var flag: Bool
    
      var body: some View {
        ZStack {
          Color.yellow.ignoresSafeArea()
          Button(
            "Button",
            action: {
              flag.toggle()
            }
          )
        }
        .transition(.opacity)
        .animation(.default)
      }
    }
    
[/code]

### withAnimation版

[code]

    import SwiftUI
    
    struct ContentView: View {
      @State var flag = false
    
      var body: some View {
        ZStack {
          if flag {
            FirstView(
              flag: $flag
            )
          } else {
            SecondView(
              flag: $flag
            )
          }
        }
      }
    }
    
    struct FirstView: View {
      @Binding var flag: Bool
    
      var body: some View {
        ZStack {
          Color.green.ignoresSafeArea()
          Button(
            "Button",
            action: {
              withAnimation {
                flag.toggle()
              }
            }
          )
        }
        .transition(.opacity)
      }
    }
    
    struct SecondView: View {
      @Binding var flag: Bool
    
      var body: some View {
        ZStack {
          Color.yellow.ignoresSafeArea()
          Button(
            "Button",
            action: {
              withAnimation {
                flag.toggle()
              }
            }
          )
        }
        .transition(.opacity)
      }
    }
    
[/code]


CC BY-SA 4.0
2021-07-26T06:31:12.783
78408
2021-07-28T00:05:54.993
9008
question
swift ios swiftui
animationモディファイアとwithAnimationの違いはなんですか？


`animation`モディファイアの説明は、次のようになっています。

> **Summary**  
>  Applies the given animation to all animatable values within this view.

_to all animatable values within this view_
とありますから、このモディファイヤが付加されたViewに内在する全てのanimatableな値(`@State`や`@Binding`のことではありません)に対するアニメーションを指定する、と言う感じですね。

あなたの、「withAnimationの場合のみアニメーションする例」では、`animation`モディファイヤが付加された`FirstView`や`SecondView`には、(`flag`で変化するような)animatableなプロパティは存在しないのだろうと考えられます。

少し修正してもらうと、`animation`モディファイヤ版でもアニメーションするようになります。

[code]

    import SwiftUI
    
    struct ContentView: View {
      @State var flag = false
    
      var body: some View {
        let bodyView = ZStack {
          if flag {
            FirstView(
              flag: $flag
            )
          } else {
            SecondView(
              flag: $flag
            )
          }
        }
        .animation(.default) //<-
        return bodyView
      }
    }
    
    struct FirstView: View {
      @Binding var flag: Bool
    
      var body: some View {
        ZStack {
          Color.green.ignoresSafeArea()
          Button(
            "Button",
            action: {
              flag.toggle()
            }
          )
        }
        .transition(.opacity)
      }
    }
    
    struct SecondView: View {
      @Binding var flag: Bool
    
      var body: some View {
        ZStack {
          Color.yellow.ignoresSafeArea()
          Button(
            "Button",
            action: {
              flag.toggle()
            }
          )
        }
        .transition(.opacity)
      }
    }
    
[/code]

ViewBuilder内のif文は`_ConditionalContent<FirstView,
SecondView>`のような謎の非公開Viewを作成する(`return
bodyView`の行にブレークポイントを置くとデバッガには表示されます)のですが、`flag`の変化に対応するanimatableな要素は、こちらに存在すると考えられる(非公開で、ドキュメントなどは無いため推定ですが)ため、それを含むViewに`animation`モディファイヤを付加すればいい、と言うことになります。


CC BY-SA 4.0
2021-07-28T00:05:54.993
78435
2021-07-28T00:05:54.993
13972
78408
answer