SwiftUI .id(_:)运行机制及配合ForEach滚动异常问题求解
问题原因
onChange修饰符挂载位置错误:你将它放在了ForEach循环体内,每生成一个Section就会新增一个监听array.count的事件。每次数组更新时,所有已存在的Section都会同时触发滚动逻辑,多次重复的滚动调用互相冲突,干扰了Form的正常布局渲染,最终出现子视图缺失的异常。- 滚动目标值计算错误:
onChange触发时拿到的count已经是数组新增元素后的最新长度,你此时传入count + 1作为滚动目标,对应的id根本不存在于数组中,无效的滚动目标也会进一步加剧布局异常。
修复方案
- 把
onChange修饰符从ForEach循环体内移到外层的Form上,全局只保留一个监听事件即可 - 把滚动目标修改为数组的最后一个元素,也就是新增的那个Section的id值
修复后可正常运行的代码如下:
import SwiftUI struct ContentView: View { @State private var array: [Int] = [1] var body: some View { ScrollViewReader { p in NavigationView { Form { ForEach(self.array, id: \.self) { num in Section { Text("Hello") Text("My name is slim shady") Text("number \(num)") } .id(num) } } .onChange(of: array.count) { count in p.scrollTo(array.last, anchor: .top) } .toolbar { ToolbarItem(placement: .bottomBar) { Button("add") { array.append(array.count + 1) } } } } } } }
内容的提问来源于stack exchange,提问作者pakobongbong
相关产品推荐
相关产品推荐

