iOS16点击Add按钮触发报错求助(iOS15运行正常)
iOS16下点击Add按钮崩溃的解决方法
问题原因
iOS16中ScrollViewReader与List的交互时序发生了变化:当你刚向数据源添加数据就立刻调用proxy.scrollTo时,新元素的视图还未完成渲染,proxy找不到对应id(你这里用元素值本身作为标识),从而触发EXC_BREAKPOINT错误。而iOS15的视图更新逻辑允许这种即时滚动操作,所以没有出现问题。
解决方案
核心是等待List完成新元素的视图渲染后再执行滚动,以下两种方式都可以解决问题:
方式一:用主队列异步延迟执行滚动
把滚动操作放到主队列异步任务中,给视图留出更新时间:
Button { data.append(data.count + 1) DispatchQueue.main.async { proxy.scrollTo(data.count - 1) } } label: { Text("Add") }
方式二:用.task监听数据源变化触发滚动
借助SwiftUI的.task修饰符,以数据源长度为依赖,在数据更新后自动执行滚动,更贴合响应式开发风格:
Button { data.append(data.count + 1) } label: { Text("Add") } .task(id: data.count) { proxy.scrollTo(data.count - 1) }
修改后的完整代码(以方式一为例)
public struct ListTest2: View { @State var data: [Int] = [] public var body: some View { ScrollViewReader { proxy in VStack { Button { proxy.scrollTo(data.count - 1) } label: { Text("goto end") } Button { proxy.scrollTo(1) } label: { Text("goto start") } Button { data.append(data.count + 1) DispatchQueue.main.async { proxy.scrollTo(data.count - 1) } } label: { Text("Add") } List { ForEach(data, id:\.self) { index in Text("\(index )") } } } .onAppear() { for index in 1...30 { data.append(index) } } } } }
内容的提问来源于stack exchange,提问作者BLACK DOG
相关产品推荐
相关产品推荐

