Another Label

The animation works great the first time the Next Question button is pressed, but there is no visible animation on subsequent button presses because the label already has an alpha value of 1. In this section, you are going to add another label to the interface. When the Next Question button is pressed, the existing label will fade out while the new label (with the text of the next question) will fade in.

At the top of ViewController.swift, replace your declaration of a single label with two labels.

@IBOutlet var questionLabel: UILabel!
@IBOutlet var currentQuestionLabel: UILabel!
@IBOutlet var nextQuestionLabel: UILabel!
@IBOutlet var answerLabel: UILabel!

Xcode flags four places where you need to replace questionLabel with one of your new labels. Update viewDidLoad() to use currentQuestionLabel. Update viewWillAppear(_:) and showNextQuestion(_:) to use nextQuestionLabel.

func viewDidLoad() {
    super.viewDidLoad()
    questionLabel.text = questions[currentQuestionIndex]
    currentQuestionLabel.text = questions[currentQuestionIndex]
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    // Set the label's initial alpha
    questionLabel.alpha = 0
    nextQuestionLabel.alpha = 0
}

@IBAction func showNextQuestion(_ sender: UIButton) {
    currentQuestionIndex += 1
    if currentQuestionIndex == questions.count {
        currentQuestionIndex = 0
    }

    let question: String = questions[currentQuestionIndex]
    questionLabel.text = question
    nextQuestionLabel.text = question
    answerLabel.text = "???"

    animateLabelTransitions()
}

Now update animateLabelTransitions() to animate the alpha of the two labels. You will fade out the currentQuestionLabel and fade in the nextQuestionLabel simultaneously.

func animateLabelTransitions() {

    // Animate the alpha
    UIView.animate(withDuration: 0.5, animations: {
        self.questionLabel.alpha = 1
        self.currentQuestionLabel.alpha = 0
        self.nextQuestionLabel.alpha = 1
    })
}

Open Main.storyboard. Now that the code has been updated for these two labels, you need to make the connections. Control-click on the View Controller to see a list of connections. Notice that the existing questionLabel is still present with a yellow warning sign next to it (Figure 8.3). Click on the x to remove this connection.

Figure 8.3  Missing connection

Screenshot of the View Controller menu with respect to animation controls.

Connect the currentQuestionLabel outlet to the existing question label by dragging from the circle next to currentQuestionLabel to the label on the canvas.

Now drag a new Label onto the interface and position it next to the existing question label. Connect the nextQuestionLabel to this new label.

You want this label to be in the same position as the existing question label. As you have likely guessed, the best way to achieve this is through constraints. Control-drag from the nextQuestionLabel to the currentQuestionLabel and select Top. Then Control-drag upward from the nextQuestionLabel to its superview and select Center Horizontally in Container.

At this point, nextQuestionLabel is misplaced. Select the label, open the Resolve Auto Layout Issues menu, and select Update Frames. The labels will now be on top of one another.

Build and run the application. Tap the Next Question button and you will see a graceful fade for both of the labels.

If you tap it again, however, no fade occurs because the nextQuestionLabel already has an alpha of 1. To fix this, you will swap the references to the two labels. When the animation completes, the currentQuestionLabel needs to be set to the onscreen label, and the nextQuestionLabel needs to be set to the offscreen label. You will use a completion handler on the animation to accomplish this.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset