SwiftUI中子视图更新异常:父ViewModel传值后循环不触发
问题解决方案
问题原因
子视图GateSectionView中用@State存储传入的data,但@State是用来管理视图内部私有状态的属性包装器,只会在视图初始化时赋值一次。当父视图里seatLayoutViewModel.totalSeats更新后,子视图的初始化方法不会重新执行,导致data一直是空数组,ForEach自然没有内容可渲染。
解决方法
删掉子视图中data的@State修饰符,把它改成普通的只读属性(let)。这样父视图传递的数据源更新时,子视图会自动重新渲染,同步最新的数组内容。
修改后的代码
子视图GateSectionView
import SwiftUI struct GateSectionView: View { // 移除@State,改为普通属性 let data: [Int] private let adaptiveColumns = [ GridItem(.adaptive(minimum: 30)) ] init(data: [Int]) { self.data = data } var body: some View { VStack(spacing: 0) { LazyVGrid(columns: adaptiveColumns) { // 用元素本身作为id更安全,避免数组顺序变化时的视图复用问题 ForEach(data, id: \.self) { element in Text("Helo") } }.padding(10) Spacer() } .cornerRadius(12) .frame(width: 780) } }
补充说明
- 如果后续子视图需要修改
data,可以把data改成@Binding var data: [Int],父视图传递时用$seatLayoutViewModel.totalSeats即可,但当前场景仅需展示数据,用let足够。 ForEach的id用\.self(数组元素本身)比\.offset(索引)更可靠,能避免数组元素顺序调整后出现的视图异常。
内容的提问来源于stack exchange,提问作者Abhayjeet Singh
相关产品推荐
相关产品推荐

