Sunset Wan
Sunset Wan

Reputation: 23

Why didn't the UI update timely when using @IBAction func?

Here is the code of @IBAction func

@IBAction func touchCard(_ sender: UIButton) {
    flipCount += 1
    if let index = buttonCollection.firstIndex(of: sender) {
        game.chooseCard(at: index)
        updateViewFromModel() // I set breakpoint at here
    }
}

Concentration.swift file, part of model of MVC

class Concentration {
var cards = [Card]()
var numberOfPairsOfCards: Int
var identifierOfOneAndOnlyOneCard: Int?  {
    didSet {
        print("identifierOfOneAndOnlyOneCard: \(identifierOfOneAndOnlyOneCard)")
    }
}

init(numberOfPairsOfCards: Int) {
    self.numberOfPairsOfCards = numberOfPairsOfCards
    for _ in 0..<numberOfPairsOfCards {
        let card = Card()
        cards += [card, card]
    }
}

func chooseCard(at Index: Int) {
    print("Index: \(Index)")
    if !cards[Index].isMatched {
        if let matchIndex = identifierOfOneAndOnlyOneCard, matchIndex != Index {
            // check if cards match
            if cards[matchIndex].identifier == cards[Index].identifier {
                cards[matchIndex].isMatched = true
                cards[Index].isMatched = true
            }
            cards[Index].isFaceUp = true
            identifierOfOneAndOnlyOneCard = nil
        } else {
            // either no cards or 2 cards are face up
            for flipDownIndex in cards.indices {
                cards[flipDownIndex].isFaceUp = false
            }
            cards[Index].isFaceUp = true
            identifierOfOneAndOnlyOneCard = Index
        }
    }
}
}

the code of func updateViewFromModel()

Card.swift file, part of model of MVC

struct Card {
var isFaceUp: Bool = false
var isMatched: Bool = false
var identifier =  getUniqueIdentifier()

static var uniqueIdentifier: Int = 0
static func getUniqueIdentifier() -> Int{
    uniqueIdentifier += 1
    return uniqueIdentifier
}
}

These code are part of project concentration game from CS193p.
When I traced the code step by step, I found something confusing.

  1. As mentioned before, I set a breakpoint at the line of updateViewFromModel() in @IBAction func touchCard(_ sender: UIButton)
  2. Then I clicked 'Run' button of Xcode
  3. The iPhone simulator came out.
  4. the default UI image without any clicking
  5. I clicked the first 'card'(actually, a button) from left to right in the first row
  6. Xcode reacted and the UI remained the same as default
  7. I started debug the code with LLDB, and I stepped into func updateViewFromModel()
  8. When I stepped over to Line 64, it showed that the isFaceUp of the first card is true because I just clicked this card.
  9. Let's go on, I stepped over to Line 68. Line 65 and 66 must be executed! What I think is that when executing Line 65 and 66, the UI is supposed to change.But, why didn't the UI update timely?
  10. I finished executing the left code in func updateViewFromModel because I didn't click any other card.
  11. Finally it came to the end of @IBAction func touchCard, the UI still remained the same as default.
  12. I clicked 'continue program execution' button, the UI responded correctly.I felt so weird.

What I want to figure out is that at Step 9 why didn't the UI update timely.

I will appreciate your help very much!

Upvotes: 0

Views: 127

Answers (2)

Abu Ul Hassan
Abu Ul Hassan

Reputation: 1396

It may be due to slow simulators as i am also facing slow simulators issue i don't know if someone else also faced this or not, I doubt your facing this issue but i am not sure.

1- There is Nothing wrong with your code update your Simulators when working with Xcode 9.2 and simulators of IOS11.

2- Give it a try on your device

Upvotes: 0

LiLi Kazine
LiLi Kazine

Reputation: 223

When you make changes on a view, it waits for a redraw cycle, thus the view won't be updated immediately. There is nothing wrong with IBAction, you put changes elsewhere and set a break point, it won't make any difference.

Upvotes: 1

Related Questions