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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 04:37:28