Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Redesign] Training Screen + Accessibility (fixes - home/language screen) #54

Merged
merged 11 commits into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 94 additions & 22 deletions VocabularyTrainer.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
{
"object": {
"pins": [
{
"package": "WaterfallTrueCompositionalLayout",
"repositoryURL": "[email protected]:eeshishko/WaterfallTrueCompositionalLayout.git",
"state": {
"branch": null,
"revision": "f45da38f2f08aa557be75f64b1b5499149ae95d9",
"version": null
}
"pins" : [
{
"identity" : "waterfalltruecompositionallayout",
"kind" : "remoteSourceControl",
"location" : "[email protected]:eeshishko/WaterfallTrueCompositionalLayout.git",
"state" : {
"revision" : "f45da38f2f08aa557be75f64b1b5499149ae95d9"
}
]
},
"version": 1
}
],
"version" : 2
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.278",
"green" : "0.278",
"red" : "0.278"
"blue" : "0x47",
"green" : "0x47",
"red" : "0x47"
}
},
"idiom" : "universal"
Expand All @@ -23,9 +23,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.741",
"green" : "0.741",
"red" : "0.741"
"blue" : "0xBD",
"green" : "0xBD",
"red" : "0xBD"
}
},
"idiom" : "universal"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.278",
"green" : "0.278",
"red" : "0.278"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xB9",
"green" : "0xB9",
"red" : "0xB9"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
12 changes: 12 additions & 0 deletions VocabularyTrainer/Assets.xcassets/SadRobot.imageset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "SadRobot.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.
1 change: 1 addition & 0 deletions VocabularyTrainer/Components/ModalCloseButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@ final class ModalCloseButton: UIButton {
layer.cornerRadius = 3
translatesAutoresizingMaskIntoConstraints = false
accessibilityLabel = Localizable.close.localize()
accessibilityTraits = .button
}
}
26 changes: 15 additions & 11 deletions VocabularyTrainer/Coordinator/MainCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,10 @@ class MainCoordinator: Coordinator {
self.navigationController = navigationController
}

func start() {
// let homeVC = HomeScreenViewController()
let homeVC = HomeViewController(viewModel: HomeViewModel(coordinator: self))
// homeVC.coordinator = self
navigationController.pushViewController(homeVC, animated: false)
}
func start() {
let homeVC = HomeViewController(viewModel: HomeViewModel(coordinator: self))
navigationController.pushViewController(homeVC, animated: false)
}

func navigateToNewLanguageViewController(newLanguageScreenProtocol: NewLanguageScreenProtocol) {
let newLanguageVC = NewLanguageViewController(delegate: newLanguageScreenProtocol)
Expand Down Expand Up @@ -55,11 +53,17 @@ class MainCoordinator: Coordinator {
navigationController.pushViewController(addNewWordVC, animated: true)
}

func navigateToTrainingViewController(with language: String) {
let trainingVC = TrainingViewController(with: language)
trainingVC.coordinator = self
navigationController.pushViewController(trainingVC, animated: true)
}
func navigateToTrainingViewController(with language: String) {
let trainingVC = TrainingViewController(with: language)
trainingVC.coordinator = self
trainingVC.modalPresentationStyle = .pageSheet
if #available(iOS 15.0, *) {
if let sheet = trainingVC.sheetPresentationController {
sheet.detents = [.medium(), .large()]
}
}
navigationController.present(trainingVC, animated: true)
}

func popVC() {
navigationController.popViewController(animated: true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,6 @@ class CollectionViewCell: UICollectionViewCell {
return stackView
}()

/// Image view showing the language's icon / image / emoji.
private let imageView: UIImageView = {
let view = UIImageView()
view.translatesAutoresizingMaskIntoConstraints = false
view.contentMode = .scaleAspectFit
view.image = UIImage(systemName: "hare")
view.clipsToBounds = true
return view
}()

private let emojiLabel: UILabel = {
let label = UILabel()
label.numberOfLines = 1
label.translatesAutoresizingMaskIntoConstraints = false
label.font = .preferredFont(forTextStyle: .headline)
return label
}()

private let background: UIView = {
let view = UIView()
view.backgroundColor = Colors.cellBackground
Expand All @@ -77,7 +59,7 @@ class CollectionViewCell: UICollectionViewCell {
func configure(with item: LanguageCellViewModel) {
titleLabel.text = item.languageName
subtitleLabel.text = item.subtitle
emojiLabel.text = item.emoji
contentView.accessibilityLabel = "\(item.languageName) \(item.subtitle)"
}

private func setUpUI() {
Expand All @@ -88,18 +70,14 @@ class CollectionViewCell: UICollectionViewCell {
labelContainer.addArrangedSubview(titleLabel)
labelContainer.addArrangedSubview(subtitleLabel)
contentView.addSubview(labelContainer)
contentView.addSubview(emojiLabel)
contentView.isAccessibilityElement = true
contentView.accessibilityTraits = [.button]
}

private func setUpConstraints() {
NSLayoutConstraint.activate([
emojiLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: Dimensions.horizontalMargin),
emojiLabel.trailingAnchor.constraint(equalTo: labelContainer.leadingAnchor, constant: -Dimensions.horizontalMargin),
emojiLabel.centerYAnchor.constraint(equalTo: labelContainer.centerYAnchor),
emojiLabel.heightAnchor.constraint(equalToConstant: Dimensions.imageWidth),
emojiLabel.widthAnchor.constraint(equalToConstant: Dimensions.imageWidth),

labelContainer.topAnchor.constraint(equalTo: contentView.topAnchor, constant: Dimensions.verticalContainerMargin),
labelContainer.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: Dimensions.horizontalMargin * 2),
labelContainer.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -Dimensions.horizontalMargin),
labelContainer.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -Dimensions.verticalContainerMargin)
])
Expand Down
74 changes: 74 additions & 0 deletions VocabularyTrainer/Home Screen/View/HomeEmptyView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//
// HomeEmptyView.swift
// VocabularyTrainer
//
// Created by Mariana Brasil on 30/07/23.
// Copyright © 2023 mic. All rights reserved.
//

import UIKit

final class HomeEmptyView: UIView {

typealias Colors = HomeViewModel.Colors

/// Image view showing the sad robot image.
private let imageView: UIImageView = {
let view = UIImageView()
view.translatesAutoresizingMaskIntoConstraints = false
view.contentMode = .scaleAspectFit
view.image = UIImage(named: "SadRobot")
view.clipsToBounds = true
view.isAccessibilityElement = false
return view
}()

/// Empty label when the user don't have any language added.
private lazy var emptyLabel: UILabel = .createLabel(font: UIFontMetrics(forTextStyle: .body)
.scaledFont(for: .systemFont(ofSize: 14, weight: .regular)),
text: Localizable.emptyLanguage.localize(),
fontColor: Colors.subtitle,
textAlignment: .center)

// MARK: - Initializer

init() {
super.init(frame: .zero)
setupUI()
setupConstraints()
}

required init?(coder: NSCoder) { nil }

// MARK: - Setup

private func setupUI() {
addSubviews([imageView, emptyLabel])
translatesAutoresizingMaskIntoConstraints = false
}

private func setupConstraints() {
NSLayoutConstraint.activate([
imageView.leadingAnchor.constraint(equalTo: leadingAnchor),
imageView.topAnchor.constraint(equalTo: topAnchor),
imageView.trailingAnchor.constraint(equalTo: trailingAnchor),
imageView.heightAnchor.constraint(equalToConstant: 70),
imageView.widthAnchor.constraint(equalToConstant: 80),

emptyLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
emptyLabel.topAnchor.constraint(equalTo: imageView.bottomAnchor, constant: 28),
emptyLabel.trailingAnchor.constraint(equalTo: trailingAnchor),
emptyLabel.bottomAnchor.constraint(equalTo: bottomAnchor),
])
}

public func startAnimation() {
UIView.animate(withDuration: 1, animations: { [weak self] in
self?.imageView.frame.origin.y -= 5
}){ [weak self] _ in
UIView.animateKeyframes(withDuration: 1, delay: 0.1, options: [.autoreverse, .repeat], animations: {
self?.imageView.frame.origin.y += 5
})
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,18 @@ final class HomeLanguageHeaderView: UIView {
typealias Colors = HomeViewModel.Colors

/// Title with trailing add button.
private let titleLabel = UILabel()
private let titleLabel: UILabel = {
let label = UILabel()
label.font = UIFontMetrics(forTextStyle: .title2).scaledFont(for: .systemFont(ofSize: 20, weight: .semibold))
label.text = Strings.headerTitle
label.accessibilityTraits = .header
return label
}()

/// Button for adding a new language.
lazy var addLanguageButton: UIButton = {
let button = UIButton(type: .contactAdd)
button.translatesAutoresizingMaskIntoConstraints = false
button.accessibilityLabel = Localizable.addNewLanguage.localize()
button.tintColor = .label
button.addAction(
.init(handler: { [weak self] _ in
Expand All @@ -37,29 +44,28 @@ final class HomeLanguageHeaderView: UIView {
/// Button for starting practicing mode.
lazy var practiceButton: UIButton = {
let button = UIButton(type: .system)
button.translatesAutoresizingMaskIntoConstraints = false
let text = NSAttributedString(string: Strings.practiceButtonTitle,
attributes: [.underlineStyle: NSUnderlineStyle.single.rawValue] )
button.setAttributedTitle(text, for: .normal)
button.tintColor = Colors.flippyGreen
button.titleLabel?.font = .preferredFont(forTextStyle: .body)
button.addAction(.init(handler: { [weak self] _ in self?.delegate?.tappedPracticeButton() }), for: .touchUpInside)
button.isHidden = true
return button
}()
/// Button for editing a language.
lazy var editButton: UIButton = {
let button = UIButton(type: .system)
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle(Strings.editButtonTitle, for: .normal)
button.tintColor = .label
button.addAction(.init(handler: { [weak self] _ in self?.delegate?.tappedEditButton() }), for: .touchUpInside)
button.isHidden = true
return button
}()
/// Stack view horizontally aligning `practiceButton` and `editButton`.
lazy var buttonStackView: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [practiceButton, editButton])
stackView.spacing = Layout.defaultMargin
stackView.translatesAutoresizingMaskIntoConstraints = false
return stackView
}()

Expand All @@ -75,14 +81,16 @@ final class HomeLanguageHeaderView: UIView {

required init?(coder: NSCoder) { nil }

func shouldHideHeaderButtons(_ isHidden: Bool) {
practiceButton.isHidden = isHidden
editButton.isHidden = isHidden
}

// MARK: - Setup

private func setupUI() {
titleLabel.font = UIFontMetrics(forTextStyle: .title2).scaledFont(for: .systemFont(ofSize: 20, weight: .semibold))
titleLabel.text = Strings.headerTitle
titleLabel.translatesAutoresizingMaskIntoConstraints = false
translatesAutoresizingMaskIntoConstraints = false
addSubviews([titleLabel, addLanguageButton, buttonStackView])
accessibilityElements = [titleLabel, addLanguageButton, buttonStackView]
}

private func setupConstraints() {
Expand All @@ -91,15 +99,14 @@ final class HomeLanguageHeaderView: UIView {
titleLabel.topAnchor.constraint(equalTo: topAnchor),
titleLabel.bottomAnchor.constraint(equalTo: bottomAnchor),

addLanguageButton.leadingAnchor.constraint(equalTo: titleLabel.trailingAnchor, constant: 8),
addLanguageButton.leadingAnchor.constraint(equalTo: titleLabel.trailingAnchor),
addLanguageButton.centerYAnchor.constraint(equalTo: titleLabel.centerYAnchor),
addLanguageButton.heightAnchor.constraint(equalToConstant: 44),
addLanguageButton.widthAnchor.constraint(equalToConstant: 44),

buttonStackView.leadingAnchor.constraint(greaterThanOrEqualTo: addLanguageButton.trailingAnchor, constant: Layout.defaultMargin),
buttonStackView.topAnchor.constraint(greaterThanOrEqualTo: topAnchor),
buttonStackView.trailingAnchor.constraint(equalTo: trailingAnchor),
buttonStackView.bottomAnchor.constraint(equalTo: bottomAnchor)
buttonStackView.topAnchor.constraint(greaterThanOrEqualTo: titleLabel.topAnchor, constant: -5),
buttonStackView.trailingAnchor.constraint(equalTo: trailingAnchor)
])
}
}
Loading
Loading