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

SwiftUI中使用ForEach为按钮动态分配数组索引的实现方法

解决方案

核心问题分析

你当前的代码存在三个关键问题:

  1. 每个ButtonView都新建了独立的GameLogic实例,导致所有按钮状态完全独立、无法共享;
  2. 所有按钮硬编码使用索引0,无法对应到0-69的不同位置;
  3. 在body中尝试递增变量会报错,因为SwiftUI的body是纯函数式的视图构建逻辑,不允许执行带有副作用的非视图代码。

修正步骤

1. 给ButtonView添加索引参数

修改ButtonView,新增一个index属性,让每个按钮明确自己对应数组的位置:

import SwiftUI

struct ButtonView: View {
    @ObservedObject var gameLogic: GameLogic
    let index: Int // 新增索引参数
    
    var body: some View {
        Button(action: { gameLogic.displayLetter(whichBox: index) }) {
            Text(gameLogic.boxLabel[index])
                .foregroundColor(.black)
                .font(.title)
                .frame(width: 30, height: 30)
                .border(gameLogic.boxOutline[index])
        }
        .disabled(gameLogic.letterBoxDisabled[index])
    }
}

2. 修正BoxView的循环逻辑

在BoxView中,通过行号和列号计算每个按钮的唯一索引(row * 7 + column),并且传递同一个GameLogic实例给所有按钮:

import SwiftUI

struct BoxView: View {
    @ObservedObject var gameLogic: GameLogic
    
    var body: some View {
        VStack {
            ForEach(0..<10, id: \.self) { row in
                HStack {
                    ForEach(0..<7, id: \.self) { column in
                        // 计算0-69的唯一索引
                        let index = row * 7 + column
                        ButtonView(gameLogic: gameLogic, index: index)
                            .frame(width: 30, height: 30)
                    }
                }
            }
        }
    }
}

关键注意事项

  • 确保GameLogic中的boxLabel、boxOutline、letterBoxDisabled三个数组的长度至少为70,否则会触发数组越界崩溃;
  • 所有按钮共享同一个GameLogic实例,这样状态变化才能在所有按钮上同步生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 06:03:30