SwiftUI ScrollView 动画滚动有时很慢

Ric*_*ick 6 ios swift swiftui

我有一个简单的聊天视图,可以向上滚动以显示出现在聊天底部的新消息。奇怪的是,有时,滚动动画的持续时间比正常情况要长得多。

显示有时缓慢的滚动行为的动画 GIF。

我认为当动画仍在进行时收到消息时就会发生这种情况。

我的代码如下所示:

struct
OverlayChatView: View
{
    @ObservedObject public  var     stream          :   ChatStream
    
    var body: some View {
        ScrollViewReader { scrollView in
            ScrollView {
                LazyVStack(alignment: .leading, spacing: 0.0) {
                    ForEach(self.stream.messages) { inMsg in
                        ChatMessageCell(message: inMsg)
                    }
                    .onChange(of: self.stream.messages, perform: { inMessages in
                        if inMessages.count < 1 { return }
                    
                        withAnimation(.linear(duration: 0.25)) {
                            scrollView.scrollTo(inMessages.last!.id, anchor: .bottom)
                        }
                    })
                    .padding(8)
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

self.stream是从一个简单的计时器传入的,@ObservedObject ChatStream每 5.0 秒插入一条新消息。如果间隔为 2.0 秒,则它只是不断地缓慢向上滚动。

我注意到的另一件事是.onChange()每个插入都会被调用三次。也许我ChatStream正在做一些愚蠢的事情。我提到它是因为仅仅快速连续调用动画三次并不会导致速度变慢。它似乎与卷轴当前所在的位置与它必须去的位置更相关。

知道如何避免这种减速吗?

小智 2

我在 iOS 14 上测试我的应用程序时遇到了这个错误(该问题似乎已在 iOS 15 中修复)。

我找到的解决方案是将 withAnimation 调用包装在主线程异步调用中,如下所示:

DispatchQueue.main.async {
    withAnimation(.linear(duration: 0.25)) {
        scrollView.scrollTo(inMessages.last!.id, anchor: .bottom)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 有趣。好吧,尽管我不在乎,那个雇主可能会崩溃。但下次我必须这样做时,我会尽力记住。 (2认同)