ScrollView 内的 LazyVStack 中具有可变高度的内容导致

Content with variable height in a LazyVStack inside a ScrollView causes stuttering / jumping(ScrollView 内的 LazyVStack 中具有可变高度的内容导致口吃/跳跃)
本文介绍了ScrollView 内的 LazyVStack 中具有可变高度的内容导致口吃/跳跃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

XCode 版本 13.0 测试版 (13A5155e)&针对 iOS 14 或 15

XCode Version 13.0 beta (13A5155e) & Targeting iOS 14 or 15

我的目标是在 SwiftUI 中创建一个聊天视图.这需要创建一个具有不同高度内容的 ScrollView.

My goal is to create a chat view in SwiftUI. This requires creating a ScrollView with content of varying heights .

经过大量调试,我确定如果您在 ScrollView 中有没有固定高度的视图,当您滚动到视图顶部时它会卡顿.

After extensive debugging, I've determined that if you have views within the ScrollView that do not have a fixed height, it will stutter when you scroll to the top of the view.

––––

项目: 下载此项目并亲自尝试

struct Message: Identifiable {
  let id = UUID()
  var text: String
}

struct ContentView: View {
  @State var items: [Message] = MockData.randomMessages(count: 100)
  
  var body: some View {
    VStack {
      Button("Shuffle items") {
        items = MockData.randomMessages(count: 100)
      }
      ScrollView {
        LazyVStack(spacing: 10) {
          ForEach(items) { item in
            Text(item.text)
              .background(colors.randomElement()!)
          }
        }
      }
    }
  }
}

我现在的结论是 LazyVStack 仅适用于具有固定高度的子视图.仅此问题就导致 SwiftUI 无法投入生产.

My conclusion right now is that LazyVStack only works with child views that have fixed height. This issue alone prevents SwiftUI from being production ready.

还有其他人解决过这个问题吗?

Has anyone else tackled this?

苹果公司的回应(2021 年 7 月 27 日):

"在您的 Mac 目标上,这一切正常,但我发现 iOS 上存在滚动问题.这个问题绝对是 iOS 上 SwiftUI 的一个 bug.我建议不要重写你的应用程序,而是为你的 UIScrollView 使用 UIViewRepresentable (或者实际上 UITable/UICollection 视图在这里最有意义).如果您使用可重用的视图,例如表格或集合,这些问题几乎肯定会消失.您不需要重写您的应用,但如果此问题阻止发布,您应该添加 UIViewRepresentable."

"On your Mac target this all works but I see there are scrolling issues on iOS. This issue is definitely a bug with SwiftUI on iOS. I recommend that rather than rewrite your app you use a UIViewRepresentable for your UIScrollView (or actually UITable / UICollection View would make the most sense here). If you use a re-usable view such as a table or collection these issues will almost certainly go away. You shouldn't need to rewrite your app but you should add a UIViewRepresentable if this issue is preventing a release."

推荐答案

在 macos 12.beta、xcode 13.beta、target ios 15 和 macCatalyst 上运行没有任何问题.在 ios15 设备和 macos 12 上测试.我也尝试使用 10000,效果很好.也许您的问题发生在较旧的 ios 和 macos 上.您可能对 Swift UI 被高频 @StateObject 更新淹没感兴趣? 代码在 ios14 而不是 ios15 上挣扎的地方.

works without any problems on macos 12.beta, xcode 13.beta, target ios 15 and macCatalyst. Tested on ios15 devices and macos 12. I also tried using 10000, and that works well. Maybe your issue happens on older ios and macos. You maybe interested in Swift UI overwhelmed by high-frequency @StateObject updates? where code struggles on ios14 but not ios15.

您可以尝试其他方法,看看是否可以提高性能,例如:

You could try other ways to see if you can improve the performance, such as:

 ForEach(items.indices, id: .self) { index in
     Text(items[index]).background(colors.randomElement()!)
 }

 ForEach(Array(items.enumerated()), id: .0) { index, item in
     Text(item).background(colors.randomElement()!)
 }

这篇关于ScrollView 内的 LazyVStack 中具有可变高度的内容导致口吃/跳跃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Why local notification is not firing for UNCalendarNotificationTrigger(为什么没有为UNCalendarNotificationTrigger触发本地通知)
iOS VoiceOver functionality changes with Bundle Identifier(IOS画外音功能随捆绑包标识符而变化)
tabbar middle tab out of tabbar corner(选项卡栏中间的选项卡角外)
Pushing UIViewController above UITabBar(将UIView控制器推送到UITabBar上方)
Dropbox Files.download does not start when number of files in folder is gt; 1000(当文件夹中的文件数为1000时,Dropbox Files.Download不会启动)
How can I sync two flatList scroll position in react native(如何在本机Reaction中同步两个平面列表滚动位置)