SwiftUI - Fast sequences of explicit animation produces strange animations
Asked Answered
S

0

1

The following code contains a list of text and a button to add more texts. When an item is added, the scroll view should scroll to the second to last (for simplicity in this example) item.

import SwiftUI

struct ContentView: View {
    
    @StateObject private var viewModel = ViewModel()
    
    var body: some View {
        createView()
    }
    
    private func createView() -> some View {
        return VStack {
            ScrollView {
                ScrollViewReader { scrollProxy in
                    VStack {
                        ForEach(viewModel.ids, id: \.self) { id in
                            Text(viewModel.texts[id]!)
                                .padding()
                        }
                    }.onAppear {
                        viewModel.scrollProxy = scrollProxy
                    }
                }
            }
            Button("Add") {
                viewModel.onAdd()
            }.padding()
        }
    }
}

class ViewModel: ObservableObject {
    @Published var ids: [UUID]
    @Published var texts: [UUID: String]
    @Published var responderID: UUID?
    
    var scrollProxy: ScrollViewProxy?
    
    init() {
        let id = UUID()
        self.ids = [id]
        self.texts = [id: "0"]
    }
    
    func onAdd() {
        
        let lastID = ids[ids.count - 1]
        
        // create new block
        let newID = UUID()
        ids.append(newID)
        self.texts[newID] = String(ids.count)
        
        withAnimation {
            scrollProxy?.scrollTo(lastID)
        }
    }
    
}

When tapping the button slowly, the scroll animation works fine.

But when the button is tapped quickly, the animation is ... broken? The animation slows to a crawl, taking a long time to complete.

So my question is, is there another way to animation the scrolling? I've tried using CADisplayLink, but the result is also pretty bad...

Subclavian answered 5/1, 2021 at 16:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.