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

SwiftUI循环生成10张不同卡片却全部显示重复问题求解

问题原因分析
  • 存储逻辑错误:你在Card类中只声明了单个result字符串属性,init方法里的10次循环每次都会覆盖上一次的生成结果,最终result只会保留最后一次生成的随机字符串,没有存储10个不同的卡片标识。
  • 视图遍历逻辑错误:EasyModeView的ForEach循环10次时,每次都读取同一个cardModel.result值,自然所有卡片展示的都是同一张图片。
  • 语法错误:随机取值的两行代码中,Int(arc4random() % 4后缺少右闭合括号,运行会直接报错。
  • 可观察对象规则不符合:ObservableObject类型的属性如果需要触发视图刷新,需要添加@Published修饰符,否则数据变化无法同步到视图。
修复后的完整代码

首先修改Card类,用数组存储10个卡片标识:

import Foundation

class Card: Identifiable, ObservableObject {
    var id = UUID()
    // 用数组存储10个不同的卡片字符串,添加@Published支持数据变化通知
    @Published var resultList: [String] = []
    
    init() {
        // 提前定义常量避免循环内重复创建
        let suitList = ["D","K","B","S"]
        let numList = ["1","2","3","4"]
        for _ in 1...10 {
            // 补全闭合括号修复语法错误
            let suit = suitList[Int(arc4random() % 4)]
            let numStr = numList[Int(arc4random() % 4)]
            // 将生成的标识添加到数组,而非覆盖单个变量
            resultList.append(suit + numStr)
        }
    }
}

再修改视图层逻辑,直接遍历生成好的卡片数组:

import SwiftUI

struct EasyModeView: View {
    @ObservedObject var cardModel: Card
    
    var body : some View {
        HStack {
            // 遍历卡片数组获取每个卡片的独立标识
            ForEach(cardModel.resultList, id: \.self) { cardStr in
                Button { } label: {
                    Image(cardStr)
                        .resizable()
                        .scaledToFit()
                }
            }
        }
    }
}
可选优化方案

如果需要保证10张卡片完全不重复,可在生成标识时增加重复校验逻辑:

while resultList.count < 10 {
    let suit = suitList[Int.random(in: 0..<3)]
    let numStr = numList[Int.random(in: 0..<3)]
    let tempStr = suit + numStr
    if !resultList.contains(tempStr) {
        resultList.append(tempStr)
    }
}

该方案使用Swift原生的random(in:)方法代替arc4random(),不需要额外类型转换,语法更简洁安全。

内容的提问来源于stack exchange,提问作者Frane Vučemilović -Vranjić

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 01:57:05