Swift 5.0+/Xcode12.5 取键值对中图片设置按钮背景报错问询
错误原因
你调用tupleDeck.index(forKey: -1)的逻辑不符合需求:该方法的作用是获取字典中指定key对应的索引位置,返回的是Dictionary<Int, Image>.Index?类型,既不是你存储的Image对象,也不遵守SwiftUI的View协议,因此background修饰符无法识别该类型,触发对应报错。
额外说明:你命名的tupleDeck本质是[Int: Image]类型的字典,不是元组(Tuple),这也是你之前查Swift tuple相关资料找不到解决方案的原因。
解决方法
你需要通过字典下标取值获取对应key的Image对象,同时处理字典下标返回的可选值,另外注意独立的PlayerHandButton结构体无法直接访问你在ContentView中定义的tupleDeck,需要将需要的背景图作为参数传入ButtonStyle:
- 修改
PlayerHandButton结构体,新增背景图参数:
struct PlayerHandButton: ButtonStyle { // 接收要显示的卡牌背景图,没有卡牌时传nil即可 let cardBackground: Image? func makeBody(configuration: Configuration) -> some View { configuration.label // 有传入卡牌就显示卡牌,没有就显示默认的空卡槽图 .background(cardBackground ?? Image("cardSpot")) } }
- 在ContentView中使用该ButtonStyle时,从
tupleDeck中取出对应Image传入即可,例如要显示数值为-1的卡牌:
Button { // 你的按钮点击交互逻辑 } label: { // 按钮的文字/图标内容 } .buttonStyle(PlayerHandButton(cardBackground: tupleDeck[-1]))
优化建议
你不需要手动声明6个Image变量再存入字典,可以直接动态生成卡牌字典,减少重复代码:
var tupleDeck: [Int: Image] = Dictionary(uniqueKeysWithValues: (-6...(-1)).map { key in let romanNum: String switch abs(key) { case 1: romanNum = "I" case 2: romanNum = "II" case 3: romanNum = "III" case 4: romanNum = "IV" case 5: romanNum = "V" case 6: romanNum = "VI" default: romanNum = "" } return (key, Image("Card_Minus_\(romanNum)")) })
预期效果

内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

