I have a background view that shows a status indicator behind the main content. I have it set to animate and I would like it to animate when the status changes, I'm passing the status to the background view. However, it's only animating the first time it appears rather than when the status is changing.
I'm using onAppear to turn the animation on, but it seems onAppear is only called the first time the view is rendered rather than when the content changes.
I've tried without success:
Using onChange(of) with the status.
Bringing the animation logic into the primary view.
I do have a workaround in my repro code (commented), but there must be a better approach.
xcode 12.4/iOS 14.4 & xcode 12.5/iOS 14.5
struct ContentView: View {
@State private var status: String = "1"
var body: some View {
VStack(spacing: 0) {
Spacer()
BackgroundView(status: status)
// This is my current workaround, but looking for a better way
// if status != "1" && status != "3" {
// BackgroundView(status: status)
// } else if status == "3" {
// BackgroundView(status: status)
// } else {
// BackgroundView(status: status)
// }
Spacer()
Button(action: {
if status == "1" {
status = "2"
} else if status == "2" {
status = "3"
} else {
status = "1"
}
}, label: {
Text("next status")
})
Spacer()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct BackgroundView: View {
var status: String = "1"
@State private var isAnimating: Bool = false
var body: some View {
ZStack {
Group {
Image(systemName: "\(status).circle.fill")
.resizable()
.scaledToFit()
.frame(width: 220)
.foregroundColor(.red)
}
.scaleEffect(isAnimating ? 1.0 : 0, anchor: .top)
}
.animation(Animation.easeOut(duration: 0.4), value: isAnimating)
.onAppear(perform: {
print("appear: \(status)")
isAnimating = true
})
// .onDisappear(perform: {
// print("disappear: \(status)")
// isAnimating = false // doesn't help
// } )
}
}
Post
Replies
Boosts
Views
Activity
I'm creating a button and animating when tapped using rotation3DEffect. However, when the button is tapped it remains opaque.
(In my actual code I'm using an image not a circle.)
I'm thinking this is a bug, but my experience with swiftui only began recently. Any thoughts appreciated.
Steve
Xcode 12.1, macOS 10.15.17, target iOS 14.1
import SwiftUI
struct ContentView: View {
@State private var spinDegrees = 0.0
@State private var spinDegrees2 = 0.0
var body: some View {
VStack{
Text("Tap Red Circle")
Button(action: {
withAnimation(.easeOut(duration: 0.8)) {
self.spinDegrees += 360
}
})
{
Circle()
.foregroundColor(.red)
.rotation3DEffect(
.degrees(spinDegrees),
axis: (x: 0.0, y: 1.0, z: 0.0)
)
}
Button("Tap here too") {
withAnimation(.easeOut(duration: 0.8)){
self.spinDegrees2 += 360
}
}
.background(Color.blue)
.foregroundColor(.white)
.rotation3DEffect(
.degrees(spinDegrees2),
axis: (x: 0.0, y: 1.0, z: 0.0)
)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}