一个简简单单的 ScrollView+LazyVGrid,就出现滚动卡顿了

68 天前
 qtoq126
import SwiftUI
import Kingfisher

struct WorksDateView: View {
    
    let columns: [GridItem] = [
        GridItem(.flexible(), spacing: 8),
        GridItem(.flexible(), spacing: 8),
        GridItem(.flexible(), spacing: 8)
    ]
        
    var data: [DateWorksModel]
            
    var body: some View {
        ScrollView {
            LazyVGrid(columns: columns, spacing: 16) {
                ForEach(data) { item in
                    Section {
                        ForEach(item.works) { work in
                            NavigationLink(destination: WorkDetailView(workId: work.id)) {
                                WorksDateCell(
                                    workImageCover: work.imageCover,
                                    workId: work.id,
                                    actressName: work.actressName,
                                    actressAvatar: work.actressAvatar
                                )
                            }
                            .buttonStyle(PlainButtonStyle())
                        }
                    } header: {
                        Text(item.releaseDate)
                            .font(.title)
                            .fontWeight(.bold)
                            .frame(maxWidth: .infinity, alignment: .leading)
                            .padding(.top, 8)
                    }
                }
            }
            .padding(.horizontal)
        }
    }
}

struct WorksDateCell: View {
    
    var workImageCover: String = "https://fakeimg.pl/320x504/fe9a2b/000"
    var workId: String = "xxx"
    var actressName: String = "xxx"
    var actressAvatar: String = "https://fakeimg.pl/60x60/ff425a/100"
    var avatarSize: CGFloat = 30.0
    
    var body: some View {
        VStack(alignment: .leading) {
            KFImage(URL(string: workImageCover))
                .placeholder {
                    ProgressView()
                }
                .resizable()
                .scaledToFit()
                .clipShape(RoundedRectangle(cornerRadius: 8, style: .continuous))
            
            HStack {
                KFImage(URL(string: actressAvatar))
                    .placeholder {
                        ProgressView()
                    }
                .resizable()
                .scaledToFill()
                .frame(width: avatarSize, height: avatarSize)
                .clipShape(Circle())
                
                VStack(alignment: .leading) {
                    Text(workId)
                        .fontWeight(.medium)
                        .font(.subheadline)
                    Text(actressName)
                        .foregroundStyle(.secondary)
                        .font(.caption)
                        .lineLimit(1)
                }
            }
        }
    }
}

实现的是一个日期的下面,展示这个日期内所有发布的 works ,如:

2024 年 10 月 10 日
work1, work2, work3
work4, work5, work6
2024 年 9 月 10 日
work5, work6, work7
work8, work9, work10

work 都是按照 LazyVGrid 布局的

我真机调试的时候,很明显的发现滚动到一定位置然后往回滚的时候,会出现卡顿,滚一段距离必定卡一下,是必现的,不知道原因在哪里

2578 次点击
所在节点    iDev
18 条回复
hwdq0012
68 天前
scrollview 一般表示无限空间吧, 里面再放个自动扩张的容器,那就变成无限扩张了
一般都会有个虚拟化技术只渲染控件看得到的区域多一点的数据

我不会 h5,但纵观微软 wpf, qt 都是如此
superkeke
68 天前
用 tableview
DLOG
68 天前
用 UICollectionView , cell 复用
项目上基本不会用到 ScrollView
Uyloal
68 天前
KFImage(URL(string: workImageCover)) 加个 .aspectRatio(504 / 320, contentMode: .fit) 试试,卡顿感应该是来自于图片实际高度和预测高度不一致,导致 ScrollView ContentSize 在变化
holy_sin
68 天前
swiftUI 处理动态大小 cell 确实坑
vvard3n
68 天前
ScrollView 没有复用机制,用 List 吧
kele999
68 天前
加载数据的时候卡一下正常的
qtoq126
68 天前
@kele999 我的图片已经都已经缓存了,不需要在加载,都是单纯的滚动卡顿
iOCZS
68 天前
lazy 对滚动并不友好,我宁愿初期白一下,后面滚动流畅,而不是快速展示,滚动的时候卡卡的。
MacsedProtoss
68 天前
这是没写过 uikit 的情况下直接写 swiftui ?正常应该没啥人会用 scrollview 写这种场景的
qtoq126
68 天前
@MacsedProtoss 没学过 uikit ,直接上手的 swiftui ,请问下 swiftui 下这种布局一般如何实现呢?
qtoq126
68 天前
@iOCZS 在 swiftui 下,有哪些更好的解决办法?
okakuyang
68 天前
你写的实际上没什么问题,swiftUI 的滚动视图比较抽象,它不像老的 UIkit 里面的 Api 定义的那么清晰。如果你想要更好的表现,可以考虑优化这个问题。

1. 图片解码时间优化
2. 第三方图片加载库与 swiftui 的兼容性问题
3. 动态计算 cell 大小问题
4. section 可能导致的布局问题
5. LazyVGrid 的 cell 缓存优先度
6. swiftui 不同版本的表现差异
7. 真机性能限制问题
keepro
68 天前
是这个服务 SysMain (维护和提高一段时间内的系统性能。)导致的,以前遇到过,查了很久。
keepro
68 天前
@keepro #7 发错贴了,对不住
magic3584
68 天前
看你近期帖子都是 SwiftUI , 建议抛弃改用 UIKit
AlwaysBee
68 天前
@Uyloal @qtoq126 #4
这个是正解
qtoq126
68 天前
@Uyloal
@AlwaysBee
赞一个,确实如此,固定了尺寸后就好了,丝滑无比,感谢大佬们

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://yangjunhui.monster/t/1122166

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX