SwiftUI ScrollPosition滚动可变高度元素不可靠的解决方案咨询
SwiftUI ScrollPosition 程序化滚动失效的解决方案求助
我的项目完全基于SwiftUI,主视图的ScrollView中包含大量高度各不相同的元素。尝试用SwiftUI的ScrollPosition实现程序化滚动到指定元素时,多数情况有效但偶尔失效,已排除自身代码存在Bug的可能。
问题演示:
完整复现代码:
import SwiftUI struct ContentView: View { @State private var position = ScrollPosition(idType: Int.self) @State private var requestedPosition: String = "" private let heights: [Double] = (0..<10_000).map { _ in Double.random(in: 150...300) } var body: some View { ScrollView { LazyVStack { ForEach(0..<10_000) { i in Text(String(i)) .frame(height: heights[i]) .frame(maxWidth: .infinity) .background(i % 2 == 0 ? Color.blue : Color.red) .id(i) } }.scrollTargetLayout(isEnabled: false) } .scrollPosition($position, anchor: .top) .overlay(alignment: .bottom) { HStack { Text("At: \(position.viewID(type: Int.self) ?? -1)") Spacer() TextField("Go to", text: $requestedPosition).frame(width: 100) Button("Go") { position.scrollTo(id: Int(requestedPosition), anchor: .top) } } .padding() .background(Color.white) } } }
操作步骤
- 在文本框中输入数字(如8674),点击"Go"跳转
- 再输入其他数字(如401、5678等)重复操作
问题表现
- 有时最终显示的视图不正确,目标ID与当前可见ID的差距越大,出现问题的概率越高
- 更严重的是:读取
position变量时,返回的是目标ID,但实际并未滚动到对应位置!这导致无法通过程序判断问题何时发生,也就无法通过延迟重试等方式补救。比如演示中尝试滚动到305,最终停在302,但position仍显示305,且305完全不在屏幕内。
问题成因推测
SwiftUI无法提前知晓每个元素的准确高度,它会计算目标元素的预估y坐标进行滚动,但偶尔会放弃精确计算,滚动到近似位置。
求助问题
如何最优地解决该问题?我知道可以用UICollectionView,但希望避免引入UIKit组件;也曾尝试多次延迟滚动,虽有改善但无法彻底解决。有没有开发者找到可行的workaround?
内容的提问来源于stack exchange,提问作者InsightClip
相关产品推荐
相关产品推荐

