SwiftUI使用scrollPosition(id:anchor:)监听滚动位置导致滚动异常
问题描述
我正尝试使用WWDC 2023发布的、适用于iOS 17和macOS 14的新API监听SwiftUI ScrollView的滚动位置。但当前视图无法正常工作:使用scrollPosition(id:anchor:)视图修饰符后,滚动视图出现异常,有时甚至初始阶段就会跳帧、卡顿。移除该修饰符后,滚动恢复正常。
相关代码片段:
ScrollView(.vertical) { LazyVGrid( columns: [.init(.adaptive(minimum: self.itemSize.width), spacing: Constants.columnSpacing, alignment: .center)], alignment: .center, spacing: Constants.sectionSpacing ) { ForEach(self.sectionData) { section in Section(section.title) { ForEach(section.items) { item in Text(item.text) .frame(width: self.itemSize.width, height: self.itemSize.height) } } } } .scrollTargetLayout() } .scrollPosition(id: self.$currentItemID) // 注释掉这行后滚动正常
请问是我使用有误,还是SwiftUI存在bug?
分析与解决建议
从代码和现象判断,这大概率是iOS 17/macOS 14初期版本中SwiftUI的框架bug,但可以先尝试以下排查手段:
- 检查
currentItemID的初始值:如果初始值不是滚动视图内的有效Item ID,框架启动时会尝试滚动到不存在的位置,引发布局异常。建议将初始值设为nil或第一个Item的ID。 - 移除
scrollPosition中的self.前缀:虽然Swift允许该写法,但在SwiftUI视图层级中直接引用self可能触发不必要的视图刷新循环,改为直接使用$currentItemID即可。 - 确认
scrollTargetLayout的作用范围:确保该修饰符直接作用于滚动内容的根容器(即示例中的LazyVGrid),不要嵌套其他容器,避免框架识别滚动目标出错。 - 升级至最新系统版本:若使用的是iOS 17.0/17.1这类早期版本,建议更新到最新正式版,苹果通常会修复这类滚动相关的布局bug。
若以上优化后问题仍存在,基本可以确定是框架bug,建议通过苹果反馈助手提交问题,并附上代码片段和录屏内容。
内容的提问来源于Stack Exchange,提问作者Tom Kraina
相关产品推荐
相关产品推荐

