-
Notifications
You must be signed in to change notification settings - Fork 12
Create a Quiz UI
Maximilian Mackh edited this page Apr 17, 2020
·
9 revisions
Let's start with an annotated example of how to create a quiz UI, displaying a question, two buttons (answer A or answer B) and a submission button. BaseComponents used in this example: ControlClosures & SplitView.
//
// QuizViewController.swift
// BaseComponents Playground
//
// Created by mmackh on 28.12.19.
// Copyright © 2019 proconsult.at gmbh. All rights reserved.
//
import UIKit
import BaseComponents
class QuizViewController: UIViewController {
// Variables for the UI components
var splitView: SplitView?
lazy var questionLabel: PerformLabel = {
return PerformLabel("")
.align(.center)
.size(.title1, [.italic, .bold])
}()
lazy var answerA: UIButton = {
return UIButton()
.size(.title2)
.addAction(for: .touchUpInside) { (button) in
self.selectAnswer(button: button)
}
}()
lazy var answerB: UIButton = {
return UIButton()
.size(.title2)
.addAction(for: .touchUpInside) { (button) in
self.selectAnswer(button: button)
}
}()
// State
var selectedAnswerButton: UIButton?
var currentQuestion: Dictionary<String,String>?
override func viewDidLoad() {
super.viewDidLoad()
title = "Quiz Time!"
view.backgroundColor = .white
// Initiate root splitView - added unowed self to prevent retain cycles
splitView = view.addSplitView(configurationHandler: { [unowned self] (splitView) in
// add top padding to account for navigation bar
splitView.insertSafeAreaInsetsPadding(form: splitView, paddingDirection: .top)
// add question label with automatic sizing, depending on content, to splitView. added padding around the label for readability
splitView.addSubview(self.questionLabel, layoutType: .automatic, edgeInsets: UIEdgeInsets(top: 20, left: 40, bottom: 20, right: 40))
// add 2 buttons for selecting the answer, each with 50% of the remaining height of the splitView
splitView.addSubview(self.answerA, layoutType: .percentage, value: 50)
splitView.addSubview(self.answerB, layoutType: .percentage, value: 50)
// add a submit button for checking the answer, height should be 54px
let submitButton = UIButton(type: .system)
.size(.title3, .bold)
.text("Submit Answer")
.text("Are you sure?", .highlighted)
.color(.background, .gray, .highlighted)
.addAction(for: .touchUpInside) { (control) in
self.submitAnswer()
}
splitView.addSubview(submitButton, layoutType: .automatic, edgeInsets: UIEdgeInsets(top: 10, left: 0, bottom: 10, right: 0))
// add bottom padding to account for the home indicator, if present (this padding will default to 0 on iPhones/iPads with a home button)
splitView.insertSafeAreaInsetsPadding(form: splitView, paddingDirection: .bottom)
})
nextQuestion()
}
var currentQuestionIdx: Int = -1
let questions = [["que":"During good weather, the sky is usually...","a":"Blue","b":"Green","ans":"a"],
["que":"Where is the city of Salzburg located?","a":"Austria","b":"Germany","ans":"a"],
["que":"What UI framework is used to develop iOS apps nativly?","a":"CocoaTouch","b":"UIKit","ans":"b"],
["que":"When it rains it ...","a":"pours","b":"waters the plants","ans":"b"]]
func nextQuestion() {
currentQuestionIdx += 1
if (currentQuestionIdx > questions.count - 1) {
currentQuestionIdx = 0
}
let question = questions[currentQuestionIdx]
questionLabel.text(question["que"])
answerA.text(question["a"])
answerB.text(question["b"])
currentQuestion = question
UIView.animate(withDuration: 0.3) {
self.splitView?.invalidateLayout()
self.selectAnswer(button: nil)
}
}
func selectAnswer(button: UIButton?) {
answerA.color(.background, UIColor.blue.withAlphaComponent(0.1))
.color(.text, .black)
answerB.color(.background, UIColor.purple.withAlphaComponent(0.1))
.color(.text, .black)
button?.color(.background, button?.backgroundColor?.withAlphaComponent(1))
.color(.text, .white)
selectedAnswerButton = button
}
func submitAnswer() {
if (selectedAnswerButton == nil) {
return
}
let selectedButton: String = (selectedAnswerButton == answerA ? "a" : "b")
let answeredCorrectly = (currentQuestion?["ans"] == selectedButton)
let alertController = UIAlertController(title: "You answered", message: (answeredCorrectly ? "Correctly, well done!" : "Incorrectly. Try again in the next round!"), preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "Next Question", style: .default, handler: { [unowned self] (action) in
self.nextQuestion()
}))
self.present(alertController, animated: true, completion: nil)
}
}