macOS SwiftUI中动态计算索引无法传递至子视图的问题
看起来你遇到的核心问题是子视图用@State存储了来自父视图的动态计算值,导致父视图更新时子视图的这个值没有同步更新。让我一步步帮你解决:
问题根源
@State是用来管理视图内部状态的,它的生命周期由SwiftUI完全掌控。当你把父视图计算出来的index传给MovieCellView的@State var index时,SwiftUI只会在初始化子视图时用这个值设置一次@State变量,之后哪怕父视图的index变化了,子视图的@State index也不会自动更新——因为SwiftUI认为这个变量是子视图自己的,外部不应该随意修改它。
解决方案
把MovieCellView里的index和tr从@State改成普通的只读参数(let),因为这两个值都是父视图传递过来的输入数据,子视图只需要使用它们,不需要修改它们:
修改后的MovieCellView代码:
struct MovieCellView: View { let index: Int // 改成let,去掉@State let tr: [String] // 同样改成let,去掉@State @State var showError: Bool = false @State var detailed: Bool = false @Binding var qualities: [String : [Int : URL]] var body: some View { // 现在这里的index会随着父视图的计算结果实时更新了 Text("\(index)") // 保留你原来的其他视图代码... } }
为什么这样有效?
当父视图因为窗口大小变化重新计算columnCount、rowsCount和每个单元格的index时,SwiftUI会重新渲染整个LazyVStack和里面的MovieCellView。此时新的index会作为参数传递给子视图,子视图会直接使用这个最新值,而不是依赖自己的内部状态。
额外说明
如果你的子视图需要修改这个index并同步回父视图,那应该用@Binding,但在你的场景里,index是由父视图根据布局动态计算的,子视图只需要使用它,所以普通的let参数完全足够。
现在你再测试窗口调整,子视图里的index应该会和父视图里的Text("\(index)")同步更新了。
内容的提问来源于stack exchange,提问作者Higherous

