SwiftUI模型的数组元素映射到Button

时间:2019-08-29 13:42:46

标签: ios swift swiftui dataflow target-action

我正在尝试使用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))
    }
}

0 个答案:

没有答案