Reputation: 133
I want to scroll a VStack
programmatically and some of child views can be animated independently, but when changing the VStack
's offset the animated child view move to its final position witth animation, that's not what I want and how to disable animating this position changes?
Here is my demo code,
import SwiftUI
struct ContentView: View {
@State var angle:Double = 0
@State var offset = 0
var body: some View {
LazyVStack {
ForEach((0..<100)) { i in
if i == 25 {
Rectangle()
.frame(width: 30, height: 30)
.animation(.none)
.rotationEffect(.degrees(angle), anchor: .center)
.animation(Animation.linear(duration: 3).repeatForever(autoreverses: false))
.onAppear {
angle = 360
}
} else {
Text("number \(i)")
}
}
}
.offset(y: CGFloat(offset))
.animation(.none)
.onAppear {
offset = 200
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Upvotes: 0
Views: 2360
Reputation: 11426
public extension View {
func animationMovementDisable() -> some View {
self
.transaction { transaction in
transaction.animation = nil
}
}
}
based on article: https://www.avanderlee.com/swiftui/disable-animations-transactions/
Upvotes: 0
Reputation: 154583
Try the following (tested in Xcode 12.0.1, iOS14):
Use an explicit animation call when setting the angle
:
import SwiftUI
struct ContentView: View {
@State var angle:Double = 0
@State var offset = 0
var body: some View {
LazyVStack {
ForEach((0..<100)) { i in
if i == 25 {
Rectangle()
.frame(width: 30, height: 30)
.rotationEffect(.degrees(angle), anchor: .center)
.onAppear {
withAnimation(Animation.linear(duration: 3).repeatForever(autoreverses: false)) {
angle = 360
}
}
} else {
Text("number \(i)")
}
}
}
.offset(y: CGFloat(offset))
.onAppear {
offset = 200
}
}
}
Upvotes: 3