0

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()
    }
}

and the effect, enter image description here

Dictator
  • 105
  • 1
  • 9

1 Answers1

3

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
        }
        
    }
}
vacawama
  • 150,663
  • 30
  • 266
  • 294
  • Anticipating your next possible issue, if your animating view scrolls offscreen and then comes back it won't be animating any longer. See [this answer](https://stackoverflow.com/a/64166004/1630618) for what is going on and how to fix that. – vacawama Oct 10 '20 at 02:11