Search code examples
iosanimationswiftuiopacity

Why does SwiftUI opacity animation fail in Gesture's onEnded method?


As shown in the gif below, the second tap on the purple rectangle does not trigger the animation for the blue rectangle to fade in. Is this a Bug or an obscure Feature?

Thanks for your kind reply!

trying to toggle the opacity of the big blue rectangle with animation (sorry, not enough reputation to post images)

struct FadeTestView: View {
  @State var fade: Bool = false
  var body: some View {
    VStack{
      Rectangle().fill(.blue).frame(width: 100, height: 100, alignment: .center)
        .opacity(fade ? 0 : 1)
      
      Button(action: {
        withAnimation(.easeInOut(duration: 2)){ fade.toggle() }
      }){
        Circle().fill(.yellow).frame(width: 50, height: 50, alignment: .center)
      }
      
      Rectangle().fill(.purple).frame(width: 50, height: 50, alignment: .center)
        .gesture(TapGesture().onEnded{
          withAnimation(.easeInOut(duration: 2)){ fade.toggle() }
        })
    }
  }
}

Solution

  • use linear if its just for change opacity

    struct FadeTestView: View {
    @State var fade: Bool = false
    var body: some View {
    VStack{
      Rectangle().fill(.blue).frame(width: 100, height: 100, alignment:       .center)
        
        .opacity(fade ? 0 : 1)
      
      Button(action: {
          withAnimation(.linear(duration: 2)){ fade.toggle() }
      }){
        Circle().fill(.yellow).frame(width: 50, height: 50, alignment: .center)
      }
      
      Rectangle().fill(.purple).frame(width: 50, height: 50, alignment: .center)
            .onTapGesture() {
                withAnimation(.linear(duration: 2)){
                    fade.toggle()
                }
            }
           
    }
    }
    
    }
    

    enter image description here