In a simple memory game I have a struct that defines the two cards that are tapped and returns in mutating functions the integers firstFlippedCard and secondFlippedCard.
If these do not match by another property, I want both cards to 'flip back'. I made a transition function for this - however, I can only make the last tapped button to switch back using the following logic:
@IBAction func cardsPress(_ sender: UIButton) {
flip(sender: sender)
if cardBrain.checkFirstCard(card: sender.tag - 1) == true {
//stay flipped
} else if cardBrain.checkForMatch(card: sender.tag - 1).match == true {
//stay flipped
} else {
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1), execute: {
self.backFlip(sender: sender)
})
}
}
Note that multiple UIButtons are linked to cardsPress. How can I make them both flip back instead of only the sender?
Add a property to keep track of the previousButton
pressed. Then use this property to flip both the current sender
and the previousButton
. Finally, set previousButton
back to nil
after flipping it or deciding to keep it flipped.
var previousButton: UIButton?
var waitForFlip = false
@IBAction func cardsPress(_ sender: UIButton) {
// ignore button input while waiting for cards to unflip
guard !waitForFlip else { return }
flip(sender: sender)
if cardBrain.checkFirstCard(card: sender.tag - 1) {
//stay flipped
previousButton = sender
} else if cardBrain.checkForMatch(card: sender.tag - 1).match {
//stay flipped
previousButton = nil
} else {
waitForFlip = true
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1), execute: {
self.backFlip(sender: sender)
if let button = previousButton {
self.backFlip(sender: button)
self.previousButton = nil
}
self.waitForFlip = false
})
}
}
Notes:
There is a possibility that the player could start flipping another card before the previous ones flip back. I introduced a waitForFlip
property to ignore button inputs while we are waiting for the mismatched cards to flip back to avoid an issue where previousButton
gets set and then overwritten to nil
by the previous unflip.
There is no need to check if a Bool
value is == true
. Simply check if boolValue {
instead of if boolValue == true
. I removed two instances of that.
You might want to disable the buttons of cards that have been flipped (set sender.isEnabled = false
) to keep the player from selecting a flipped card. Remember to reenable them again when they are flipped back by setting their isEnabled
properties to true
.