You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用.id()变更时LazyVGrid未重绘的问题排查

问题原因与解决方案

问题根源

你在使用Identifiable的Item结构体时,给ForEach的返回视图添加了.id(selectedItemIndex)修饰符,这干扰了SwiftUI的视图更新机制:

  • 对于基于Identifiable元素的ForEach,SwiftUI会通过元素的id来跟踪、复用子视图。添加的全局.id(selectedItemIndex)会让SwiftUI在状态变化时,错误地复用旧的子视图实例,导致即使selectedItemIndex已更新,视图的颜色、zIndex等视觉属性也不会重新计算。
  • 而在使用Range的有效代码中,由于Range元素没有Identifiable标识,SwiftUI无法通过元素ID跟踪视图,此时.id(selectedItemIndex)会触发整个ForEach的重建,从而正确更新所有子视图的视觉属性。

解决方案

移除ForEach后面的.id(selectedItemIndex)修饰符,让每个子视图自然响应selectedItemIndex的状态变化即可:

import SwiftUI

struct Item : Identifiable, Hashable {
    var id: Int
}

let data = (1...12).map { index in
    Item(id: index)
}

struct ZIndexInLazyVGridUpdateContainerExperiment: View {
    @State private var selectedItemIndex: Int = 5
    
    var body: some View {
        ZStack {
            Color.black.ignoresSafeArea()
            ScrollView {
                LazyVGrid(columns: [GridItem(), GridItem(), GridItem()]) {
                    ForEach(data) { item in
                        Rectangle()
                            .fill(Color(
                                red: 0,
                                green: 0.5,
                                blue: selectedItemIndex == item.id ? 1 : Double(item.id)/24.0 + 0.5))
                            .zIndex(selectedItemIndex == item.id  ? 1 : 0)
                            .frame(width: 180, height: 180)
                            .border(.black)
                            .rotationEffect(.degrees(45))
                            .onTapGesture {
                                selectedItemIndex = item.id
                                print("selected item \(selectedItemIndex)")
                            }
                    }
                    // 移除此处的.id(selectedItemIndex)
                }
            }
        }
    }
}

补充说明

如果在复杂场景下确实需要强制刷新整个ForEach,可以将data改为@State变量,或通过@Binding传递状态,但在当前场景下,移除全局.id修饰符已足够解决问题。

内容的提问来源于stack exchange,提问作者mcx maja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 10:42:06