SwiftUI Custom View repeat forever animation show as unexpected
This looks like a bug of NavigationView
: without it animation works totally fine. And it wan't fixed in iOS15.
Working solution is waiting one layout cycle using DispatchQueue.main.async
before string animation:
struct LoadingView: View {
@State private var isLoading = false
var body: some View {
Circle()
.trim(from: 0, to: 0.8)
.stroke(Color.red, lineWidth: 5)
.frame(width: 30, height: 30)
.rotationEffect(Angle(degrees: isLoading ? 360 : 0))
.onAppear {
DispatchQueue.main.async {
withAnimation(.linear(duration: 1).repeatForever(autoreverses: false)) {
self.isLoading.toggle()
}
}
}
}
}
SwiftUI: Broken explicit animations in NavigationView?
Here is fixed part (another my answer with explanations is here).
Tested with Xcode 12 / iOS 14.
struct EscapingAnimationTest_Inner: View {
@State var degrees: CGFloat = 0
var body: some View {
Circle()
.trim(from: 0.0, to: 0.3)
.stroke(Color.red, lineWidth: 5)
.rotationEffect(Angle(degrees: Double(degrees)))
.animation(Animation.linear(duration: 1).repeatForever(autoreverses: false), value: degrees)
.onAppear() {
DispatchQueue.main.async { // << here !!
degrees = 360
}
}
}
}
Update: the same will be using withAnimation
.onAppear() {
DispatchQueue.main.async {
withAnimation(Animation.linear(duration: 1).repeatForever(autoreverses: false)) {
degrees = 360
}
}
}
SwiftUI: Animation Inside NavigationView
The onAppear is called too early when view frame is zero being in NavigationView, so animation is applied to change from zero to value.
Here is valid workaround. Tested with Xcode 12.4 / iOS 14.4
var body: some View {
ZStack() {
Color.clear
Rectangle()
.frame(width: animate ? finalRect.width: currentRect.width, height: animate ? finalRect.height: currentRect.height, alignment: .center)
.animation(animation, value: animate)
.onAppear {
DispatchQueue.main.async {
// << postpone till end of views construction !!
animate = true
}
}
}
}
Note: almost any why question can be answered only by Apple... maybe it is a bug, maybe an implementation specifics.
Related Topics
Cannot Convert Value of Type 'Nsmutablearray' to Expected Argument Type '[Skaction]'
Swift Unsafemutablepointer & Unsafemutablepointer<Unsafepointer<Sometype>>
Automatically Reload Tableviewcontroller on Rewind
Trouble Calling a Method in an Init
Swift: Convert Byte Array into Ciimage
Bar Button Item Tint Color Not Working
How to Insert a Row in Tableview Without Using Reloaddata Function in Cocoa
Prevent Retain Cycle in Swift Function Pointers
How to Update Nslayoutconstraint in a UItableviewcell of Dynamic Height
Popping Noise Between Audioqueuebuffers
Xcode8 Beta 6 - Urlsession with Completionhandler Argument Not Working
Continuous Rotation of Nsimageview (So It Appears to Be Animated)
How to Add UIpickerview in UIalertcontroller
Non-Translucent UItabbar Creates Strange Grey Bar
How to Reconnect Akplayer and Akmixer After Audiokit.Stop()
Tintcolor Not Changing for UIbarbuttonitem for .Normal Stage in Case of iOS 13.2