我正在尝试使用SwiftUI(所有权利均属于他们)解决CS193P Stanford的iOS课程(Set游戏)的作业2。 该任务要求显示设置好的卡片组中的卡片,分发更多卡片,选择3张卡片,尝试匹配它们,然后取消选择它们。
1)是否可以即时使用模型的数组元素“更新” UI卡(可变性),还是应该在每次处理更多卡时(不可变性)创建新的UI卡?以及如何使用SwiftUI实现这一目标?
2)第二个问题更基本:如何确定轻按了哪个按钮?我的意思是如何将模型的数组元素映射到SwiftUI的按钮,所以在按钮的动作块中,我知道哪个模型的元素与此特定按钮相关联?我遇到的所有示例都具有触发某些操作的Button,这些按钮与所点击的确切按钮无关,他们不必在其操作块中确定按钮。
3)“在视图更新期间修改状态,这将导致未定义的行为。”如果我需要模型的结构可变(实际上是在体内),该如何处理?
任何帮助和解释都将受到高度赞赏。这是我的代码(在设计之初尚未完成,但在继续进行之前,我想了解所提到的问题):
import SwiftUI
struct ContentView: View {
@State var setDeck: SetDeck = SetDeck()
var body: some View {
var initialCards = setDeck.initialDeal()
let stack = VStack() {
ForEach((0..<SetDeck.maximumCardsCount / 4), id: \.self) { num in
HStack {
ForEach((1...4), id: \.self) { currentNum in
// How to get ID of card here?
StatedButton(deselectable: self.$setDeck.deselectable, action: {
self.setDeck.selectCard(id: ???)
}) {() -> Text? in
if initialCards.count > 0 {
let card = initialCards.removeFirst()
return self.getCardSymbol(from: card)//Text("\(card.rank.rawValue)")
} else {
return nil
}
}
}
}
}
Spacer()
Button(action: {
print("Deal 3 more tapped")
}) {
Text("Deal 3 more cards")
}
}
return stack
}
func getCardSymbol(from card: SetCard, selected: Bool = false) -> Text {
let color: UIColor
let rank = card.rank.rawValue
var symbol = ""
switch card.color {
case .red:
color = .red
case .green:
color = .green
case .purple:
color = .purple
}
switch card.shape {
case .triangle:
for _ in 1...rank {
symbol += "▲"
}
case .circle:
for _ in 1...rank {
symbol += "●"
}
case .square:
for _ in 1...rank {
symbol += "■"
}
}
var text = Text("\(symbol)")
switch card.shading {
case .solid:
text = text.foregroundColor(Color(color))
case .striped:
text = text.foregroundColor(Color(color.withAlphaComponent(0.3)))
case .open:
text = text.foregroundColor(Color(color.withAlphaComponent(0.1))).underline(true, color: Color(color))
}
return text
.font(Font.system(.headline))
}
}