Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
522 views
in Technique[技术] by (71.8m points)

swift - SwiftUI ScrollView not following the chained animation

Back again for some SwiftUI issues. haha

So I have a scroll view, and I simulate a user switching elements in the scrollview pretty fast. (ex. Music Lyrics that adjust to where the user is listening).

My issue here is the animation are not following the speed and I was wondering if there was a way to prevent that. Cancel the previous animation for example? I haven't found anything atm to fix this problem.

The following code is used to reproduce the Animation issue.

import SwiftUI

struct ContentView: View {
    @ObservedObject var viewModel = ViewModel()

    var body: some View {
        ScrollView(showsIndicators: false, content: {
            ScrollViewReader(content: { scrollViewProxy in
                LazyVStack(content: {
                    ForEach(viewModel.fragments, id: .id) { fragment in
                        Text(fragment.content + fragment.id)
                            .background(fragment == viewModel.currentFragment ? Color.yellow : Color.gray)
                            .frame(height: 100)
                            .font(.largeTitle)
                            .id(fragment.id)
                    }
                })
                .id("ContentView-LazyVStack-Animation")
                .onReceive(viewModel.$currentFragment, perform: { currentFragment in
                    guard let currentFragment = currentFragment else {
                        return
                    }
                    withAnimation(.easeInOut(duration: 2)) {
                        scrollViewProxy.scrollTo(currentFragment.id, anchor: .center)
                    }
                })
            })
        })
        .id("ContentView-ScrollView-Animation")
    }
}

final class ViewModel: ObservableObject {
    @Published var fragments: [Fragment] = [Int](0..<100).map({ Fragment(id: "($0)", content: "Some text yeah! super cool.") })
    @Published var currentFragment: Fragment?

    private var scrollingTimer: Timer?

    init() {
        currentFragment = fragments.first

        setupRandomScroll()
    }

    func setupRandomScroll() {
        scrollingTimer = Timer.scheduledTimer(withTimeInterval: 0.2,
                                              repeats: true,
                                              block: { [weak self] _ in
                                                guard let self = self else {
                                                    return
                                                }
                                                let newIndex = Int.random(in: 70..<100)
                                                self.currentFragment = self.fragments[newIndex]
                                              })
    }
}

final class Fragment: ObservableObject, Equatable, Hashable {
    var id: String
    @Published var content: String

    init(id: String, content: String) {
        self.id = id
        self.content = content
    }

    static func == (lhs: Fragment, rhs: Fragment) -> Bool {
        return lhs.id == rhs.id
    }

    func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }
}

Thanks in advance for any help given! :)

question from:https://stackoverflow.com/questions/65931284/swiftui-scrollview-not-following-the-chained-animation

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...