Skip to content

Commit

Permalink
hq-4: Question Screen
Browse files Browse the repository at this point in the history
  • Loading branch information
Vadim Aleshin authored and Vadim Aleshin committed Dec 17, 2023
1 parent 35c0de0 commit e43464c
Show file tree
Hide file tree
Showing 31 changed files with 579 additions and 3 deletions.
Binary file modified .DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.DS_Store
.DS_Store
30 changes: 29 additions & 1 deletion quizzz/quizzz.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
A67A695F2B2E08C0002B59DF /* QuestionStatusCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A67A695A2B2E08C0002B59DF /* QuestionStatusCollectionViewCell.swift */; };
A67A69602B2E08C0002B59DF /* TopAlignedCollectionViewFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = A67A695B2B2E08C0002B59DF /* TopAlignedCollectionViewFlowLayout.swift */; };
A67A69642B2E08C8002B59DF /* Collection+safe.swift in Sources */ = {isa = PBXBuildFile; fileRef = A67A69622B2E08C8002B59DF /* Collection+safe.swift */; };
A67A69672B2EFA08002B59DF /* QuestionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A67A69662B2EFA08002B59DF /* QuestionView.swift */; };
A67A69692B2EFCD9002B59DF /* AnswerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A67A69682B2EFCD9002B59DF /* AnswerView.swift */; };
A67A696C2B2EFE30002B59DF /* AnswerViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A67A696B2B2EFE30002B59DF /* AnswerViewCell.swift */; };
A67A696E2B2F0719002B59DF /* QuestionViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A67A696D2B2F0719002B59DF /* QuestionViewModel.swift */; };
A67A69702B2F0FCD002B59DF /* QuestionRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = A67A696F2B2F0FCD002B59DF /* QuestionRouter.swift */; };
A7F247622B2DCC0B00A267E5 /* MainScreenCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7F247612B2DCC0B00A267E5 /* MainScreenCell.swift */; };
B4B317D42B2E0421005FA6C4 /* RuleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4B317D32B2E0421005FA6C4 /* RuleView.swift */; };
B4B317D62B2E0474005FA6C4 /* RuleCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4B317D52B2E0474005FA6C4 /* RuleCollectionViewCell.swift */; };
Expand All @@ -41,6 +46,11 @@
A67A695A2B2E08C0002B59DF /* QuestionStatusCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QuestionStatusCollectionViewCell.swift; sourceTree = "<group>"; };
A67A695B2B2E08C0002B59DF /* TopAlignedCollectionViewFlowLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TopAlignedCollectionViewFlowLayout.swift; sourceTree = "<group>"; };
A67A69622B2E08C8002B59DF /* Collection+safe.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Collection+safe.swift"; sourceTree = "<group>"; };
A67A69662B2EFA08002B59DF /* QuestionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuestionView.swift; sourceTree = "<group>"; };
A67A69682B2EFCD9002B59DF /* AnswerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnswerView.swift; sourceTree = "<group>"; };
A67A696B2B2EFE30002B59DF /* AnswerViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnswerViewCell.swift; sourceTree = "<group>"; };
A67A696D2B2F0719002B59DF /* QuestionViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuestionViewModel.swift; sourceTree = "<group>"; };
A67A696F2B2F0FCD002B59DF /* QuestionRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuestionRouter.swift; sourceTree = "<group>"; };
A7F247612B2DCC0B00A267E5 /* MainScreenCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainScreenCell.swift; sourceTree = "<group>"; };
B4B317CD2B2DEEAA005FA6C4 /* FlyingEmojis.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = FlyingEmojis.framework; sourceTree = BUILT_PRODUCTS_DIR; };
B4B317D32B2E0421005FA6C4 /* RuleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -103,6 +113,8 @@
A67A69542B2E08C0002B59DF /* Questions */ = {
isa = PBXGroup;
children = (
A67A696F2B2F0FCD002B59DF /* QuestionRouter.swift */,
A67A696D2B2F0719002B59DF /* QuestionViewModel.swift */,
A67A69552B2E08C0002B59DF /* QuestionViewController.swift */,
A67A69562B2E08C0002B59DF /* Views */,
);
Expand All @@ -112,7 +124,9 @@
A67A69562B2E08C0002B59DF /* Views */ = {
isa = PBXGroup;
children = (
A67A696A2B2EFE17002B59DF /* AnswerView */,
A67A69572B2E08C0002B59DF /* QuestionStatusView */,
A67A69662B2EFA08002B59DF /* QuestionView.swift */,
);
path = Views;
sourceTree = "<group>";
Expand All @@ -137,7 +151,16 @@
path = Extensions;
sourceTree = "<group>";
};
A7F247602B2DCBEE00A267E5 /* MainScreen */ = {
A67A696A2B2EFE17002B59DF /* AnswerView */ = {
isa = PBXGroup;
children = (
A67A69682B2EFCD9002B59DF /* AnswerView.swift */,
A67A696B2B2EFE30002B59DF /* AnswerViewCell.swift */,
);
path = AnswerView;
sourceTree = "<group>";
};
A7F247602B2DCBEE00A267E5 /* MainScreenViewController */ = {
isa = PBXGroup;
children = (
A676A2AC2B2D9A52002DA5F4 /* MainScreenViewController.swift */,
Expand Down Expand Up @@ -287,16 +310,21 @@
B4B317D82B2E04D2005FA6C4 /* RulesViewController.swift in Sources */,
A676A2AD2B2D9A52002DA5F4 /* MainScreenViewController.swift in Sources */,
A67A695E2B2E08C0002B59DF /* QuestionStatusView.swift in Sources */,
A67A69692B2EFCD9002B59DF /* AnswerView.swift in Sources */,
A67A69702B2F0FCD002B59DF /* QuestionRouter.swift in Sources */,
A67A695C2B2E08C0002B59DF /* QuestionViewController.swift in Sources */,
A7F247622B2DCC0B00A267E5 /* MainScreenCell.swift in Sources */,
B4B317D62B2E0474005FA6C4 /* RuleCollectionViewCell.swift in Sources */,
A67A695F2B2E08C0002B59DF /* QuestionStatusCollectionViewCell.swift in Sources */,
A676A2A92B2D9A52002DA5F4 /* AppDelegate.swift in Sources */,
A67A69642B2E08C8002B59DF /* Collection+safe.swift in Sources */,
A67A696E2B2F0719002B59DF /* QuestionViewModel.swift in Sources */,
A67A69672B2EFA08002B59DF /* QuestionView.swift in Sources */,
A67A69602B2E08C0002B59DF /* TopAlignedCollectionViewFlowLayout.swift in Sources */,
A676A2AB2B2D9A52002DA5F4 /* SceneDelegate.swift in Sources */,
B4B317D42B2E0421005FA6C4 /* RuleView.swift in Sources */,
A67A695D2B2E08C0002B59DF /* QuestionStatusCellType.swift in Sources */,
A67A696C2B2EFE30002B59DF /* AnswerViewCell.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<key>quizzz.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
<integer>2</integer>
</dict>
</dict>
</dict>
Expand Down
6 changes: 6 additions & 0 deletions quizzz/quizzz/Assets.xcassets/Colors/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
6 changes: 6 additions & 0 deletions quizzz/quizzz/Assets.xcassets/Images/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"images" : [
{
"filename" : "Vector.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions quizzz/quizzz/Helpers/Assets.xcassets/Colors/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.275",
"green" : "0.729",
"red" : "0.282"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.239",
"green" : "0.239",
"red" : "0.894"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
6 changes: 6 additions & 0 deletions quizzz/quizzz/Helpers/Assets.xcassets/Images/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "hola_logo_512 (1).png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "hola_logo_1024 (1).png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "hola_logo_2048 (1).png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"images" : [
{
"filename" : "Vector.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 35 additions & 0 deletions quizzz/quizzz/Screens/Questions/QuestionRouter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// QuestionRouter.swift
// quizzz
//
// Created by Vadim Aleshin on 17.12.2023.
//

import UIKit

protocol QuestionRouterProtocol {
func showFinishAlert(answers: [Bool])
func close()
}

struct QuestionRouter {
weak var controller: QuestionViewController?
}

// MARK: - QuestionRouterProtocol

extension QuestionRouter: QuestionRouterProtocol {
func showFinishAlert(answers: [Bool]) {
let alert = UIAlertController(
title: "The End",
message: "Question count - \(answers.count), lose - \(answers.filter { !$0 }.count)",
preferredStyle: .alert
)

controller?.present(alert, animated: true)
}

func close() {
controller?.dismiss(animated: true)
}
}
105 changes: 104 additions & 1 deletion quizzz/quizzz/Screens/Questions/QuestionViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,116 @@
//

import UIKit
import FlyingEmojis

final class QuestionViewController: UIViewController {

private lazy var statusView: QuestionStatusView = .init(frame: .zero)
private lazy var questionView: QuestionView = .init()
private lazy var answerView: AnswerView = .init()
private lazy var emojisBackground: ParticleAnimationView = .init()
private lazy var backButton: UIButton = makeBackButton()

var viewModel: QuestionViewModelProtocol!
var router: QuestionRouterProtocol!

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
addSubviews()
setupConstraints()
setup()
}

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
emojisBackground.updateBounds()
}

private func setup() {
viewModel.delegate = self
viewModel.setup()

answerView.handler = { [weak self] id in
let flag = self?.viewModel.answerForQuestion(id) ?? false
self?.statusView.nextStep(with: flag)
self?.viewModel.nextQuestion()
}

emojisBackground.update(with: .init(
mainImage: "🤡".toImage(),
secondaryImage: "🎪".toImage(),
tertiaryImage: "🎠".toImage()
))
}

private func addSubviews() {
view.addSubview(emojisBackground)
view.addSubview(backButton)
view.addSubview(statusView)
view.addSubview(questionView)
view.addSubview(answerView)
}

private func setupConstraints() {
emojisBackground.translatesAutoresizingMaskIntoConstraints = false
backButton.translatesAutoresizingMaskIntoConstraints = false
statusView.translatesAutoresizingMaskIntoConstraints = false
questionView.translatesAutoresizingMaskIntoConstraints = false
answerView.translatesAutoresizingMaskIntoConstraints = false

NSLayoutConstraint.activate([
emojisBackground.topAnchor.constraint(equalTo: view.topAnchor),
emojisBackground.leftAnchor.constraint(equalTo: view.leftAnchor),
emojisBackground.rightAnchor.constraint(equalTo: view.rightAnchor),
emojisBackground.bottomAnchor.constraint(equalTo: view.bottomAnchor),

backButton.heightAnchor.constraint(equalToConstant: 45),
backButton.widthAnchor.constraint(equalTo: backButton.heightAnchor),
backButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 36),
backButton.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 26),

statusView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
statusView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
statusView.topAnchor.constraint(equalTo: backButton.bottomAnchor, constant: 20),
statusView.heightAnchor.constraint(equalToConstant: 80),

questionView.topAnchor.constraint(equalTo: statusView.bottomAnchor, constant: 50),
questionView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
questionView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
questionView.heightAnchor.constraint(equalTo: questionView.widthAnchor, multiplier: 0.597),

answerView.topAnchor.constraint(equalTo: questionView.bottomAnchor, constant: 50),
answerView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
answerView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
answerView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -50)
])
}

@objc private func didTapBackButton() {
router.close()
}
}

extension QuestionViewController: QuestionViewModelDelegate {
func nextQuestion(_ question: QuestionViewModel.Question) {
questionView.configure(question.title)
answerView.configure(question.answers)
}

func questionOver(_ answer: [Bool]) {
router.showFinishAlert(answers: answer)
}
}

// MARK: - Factory
extension QuestionViewController {
private func makeBackButton() -> UIButton {
let button = UIButton()
button.backgroundColor = .white
button.setImage(.backArrow, for: .normal)
button.layer.cornerRadius = 45.0 / 2.0
button.layer.cornerCurve = .circular
button.addTarget(self, action: #selector(didTapBackButton), for: .touchUpInside)
return button
}
}
Loading

0 comments on commit e43464c

Please sign in to comment.