Search code examples
iosswiftuikit

UIButton color not restored to original color


I am making a quiz app. Its button colour changes if clicked based on correct or wrong answer. But I want to restore the color to the original one after some delay. The color is changed but not restored to the default after the delay of 0.2 seconds.

Here is my code:

import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var questionLabel: UILabel!
    @IBOutlet weak var progressBar: UIProgressView!
    @IBOutlet weak var falseButton: UIStackView!
    @IBOutlet weak var trueButton: UIStackView!

    var QuestionNumber=0
    var score=0
    var questionArray = [
        Question(q: "A slug's blood is green.", a: "True"),
        Question(q: "Approximately one quarter of human bones are in the feet.", a: "True"),
        Question(q: "The total surface area of two human lungs is approximately 70 square metres.", a: "True"),
        Question(q: "In West Virginia, USA, if you accidentally hit an animal with your car, you are free to take it home to eat.", a: "True"),
        Question(q: "In London, UK, if you happen to die in the House of Parliament, you are technically entitled to a state funeral, because the building is considered too sacred a place.", a: "False"),
        Question(q: "It is illegal to pee in the Ocean in Portugal.", a: "True"),
        Question(q: "You can lead a cow down stairs but not up stairs.", a: "False"),
        Question(q: "Google was originally called 'Backrub'.", a: "True"),
        Question(q: "Buzz Aldrin's mother's maiden name was 'Moon'.", a: "True"),
        Question(q: "The loudest sound produced by any animal is 188 decibels. That animal is the African Elephant.", a: "False"),
        Question(q: "No piece of square dry paper can be folded in half more than 7 times.", a: "False"),
        Question(q: "Chocolate affects a dog's heart and nervous system; a few ounces are enough to kill a small dog.", a: "True")
    ]

    override func viewDidLoad() {
        super.viewDidLoad()
        //fill the current question on screem
        updateUI()
    }
    
    @IBAction func answerButtonPressed(_ sender: UIButton) {
        // checking question not going to out of bound
        if QuestionNumber + 1 < questionArray.count
        {
            let userAnswer = sender.currentTitle
            
            let actualAnswer = questionArray[QuestionNumber].answer
           
            if userAnswer == actualAnswer
            {   // change the backgroundcolor
                sender.backgroundColor=UIColor.green
                score+=1
            }
            else
            {   sender.backgroundColor=UIColor.red
                score-=1
            }
            QuestionNumber+=1
            // let some delay  0.2sec 
            Timer.scheduledTimer(timeInterval: 0.2, target: self, selector: #selector(updateUI), userInfo: nil, repeats: false)
           
        }
       else
        {
           questionLabel.text="Done. Your score is \(score)"
           print(score)
          
       }
    }

    @objc func updateUI()
    {
        questionLabel.text=questionArray[QuestionNumber].text
        trueButton.backgroundColor=UIColor.clear
        falseButton.backgroundColor=UIColor.clear
        
        print("color changed")
    }
}

Solution

  • a very simple solution for your case is using GCD instead of Timer: Just replace this:

    Timer.scheduledTimer(timeInterval: 0.2, target: self, selector: #selector(updateUI), userInfo: nil, repeats: false)
    

    with this:

    DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
        self.questionLabel.text = self.questionArray[QuestionNumber].text
        sender = UIColor.clear
        print("color changed")
    }
    

    To fix the problem without GCD is:

    1. Go to your Storyboard or Xib
    2. Reattach your UIButtons instead of UIStackViews. Now you attached UIStackViews to view controller instead of UIButtons.