1

Going by examples we can see that it is possible to animate different properties with different animations. For example:

Button("Tap me") {self.isShowingRed.toggle()}
    .frame(width: 200, height: 200)
    .background(isShowingRed ? Color.red : Color.blue)
    .animation(.easeIn(duration: 2.5))
    .clipShape(RoundedRectangle(cornerRadius: isShowingRed ? 50 : 0))
    .animation(Animation.easeInOut(duration: 0.1).repeatCount(5))

This code will animate the button background from red to blue in 2.5 seconds, while animating the corner radius from 0 to 50 with 5 repetitions.

The problem appears as soon as the view is embedded:

VStack {
    Button("Tap me") {self.isShowingRed.toggle()}
        .frame(width: 200, height: 200)
        .background(isShowingRed ? Color.red : Color.blue)
        .animation(.easeIn(duration: 2.5))
        .clipShape(RoundedRectangle(cornerRadius: isShowingRed ? 50 : 0))
        .animation(Animation.easeInOut(duration: 0.1).repeatCount(5))
    } 
}

When the button is embedded only the first animation is used, in this case both the color and the radius will be animated in 2.5 seconds with no repetitions.

Even if I make the button a separate component, the same problem persists.

Am I doing something wrong or is this a SwiftUI bug?

Edit: I'm using Xcode 11.1 and testing on the simulator.

1
  • at xCode 11.2 it seems that nothing changes and doesn't matter is button embed in VStack or not Commented Nov 8, 2019 at 13:41

3 Answers 3

1

As I observed when something unexpected happens when there is .background, then issue is in it... In your use-case the animation must be applied to background content and this solves the problem.

Here is example I used and it animates as you wanted with and w/o container.

import SwiftUI

struct TestButtonAnimation: View {
    @State private var isShowingRed = false
    var body: some View {
        VStack {
            Button("Tap me") {self.isShowingRed.toggle()}
                .frame(width: 200, height: 200)
                .background(
                    Group {isShowingRed ? Color.red : Color.blue}
                    .animation(.easeIn(duration: 2.5))
                )
                .clipShape(RoundedRectangle(cornerRadius: isShowingRed ? 50 : 0))
                .animation(Animation.easeInOut(duration: 0.1).repeatCount(5))
        }
    }
}

struct TestButtonAnimation_Previews: PreviewProvider {
    static var previews: some View {
        TestButtonAnimation()
    }
}

Tested with: Xcode 11.1

Sign up to request clarification or add additional context in comments.

1 Comment

Although this is a workaround for background, the same problem can be reproduced with offset, and other properties in which you can't embed the animation.
0

You may try this way .animation(.default) in the container

  var body: some View {
  VStack{
  Button("Tap me") {self.isShowingRed.toggle()}
 .frame(width: 200, height: 200)
 .background(isShowingRed ? Color.red : Color.blue)
 .animation(.easeIn(duration: 2.5))
.clipShape(RoundedRectangle(cornerRadius: isShowingRed ? 50 : 0))
.animation(Animation.easeInOut(duration: 0.1).repeatCount(5))
}.animation(.default)
}

Comments

0

After updating to Xcode 11.2.1 this issue was resolved.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.