From d29dae5c79d6450d43840bc2f30240410315829e Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Wed, 20 Mar 2024 02:34:25 +0100 Subject: [PATCH] Implemented the FeedItemViewController view controller in the Feed framework. --- .../FeedItemViewController.swift | 189 +++++++++++++----- 1 file changed, 139 insertions(+), 50 deletions(-) diff --git a/Frameworks/Feed/Bundle/Sources/UI/View Controllers/FeedItemViewController.swift b/Frameworks/Feed/Bundle/Sources/UI/View Controllers/FeedItemViewController.swift index 621471e..791b869 100644 --- a/Frameworks/Feed/Bundle/Sources/UI/View Controllers/FeedItemViewController.swift +++ b/Frameworks/Feed/Bundle/Sources/UI/View Controllers/FeedItemViewController.swift @@ -6,6 +6,8 @@ // Copyright © 2020 ING. All rights reserved. // +import ReviewsUIKit +import SwiftUI import UIKit final class FeedItemViewController: UIViewController { @@ -13,29 +15,49 @@ final class FeedItemViewController: UIViewController { // MARK: Constants private let item: Review + // MARK: Properties + private lazy var appVersionController = { + UIHostingController(rootView: FakeLabel( + systemIcon: .Icon.info, + title: item.rating.appVersion + )) + }() + + private lazy var authorController = { + UIHostingController(rootView: FakeLabel( + systemIcon: .Icon.person, + title: item.author + )) + }() + + private lazy var starRatingController = { + UIHostingController(rootView: StarRating( + item.rating.stars, + of: .Rating.total + )) + }() + // MARK: Outlets - private lazy var titleLabel = { - let label = UILabel() - - label.font = UIFont.preferredFont(forTextStyle: .title3) - label.numberOfLines = 0 - label.translatesAutoresizingMaskIntoConstraints = false - label.text = item.title - - return label - }() - - private lazy var authorLabel = { - let label = UILabel() + private lazy var appVersionView = { + guard let view = appVersionController.view else { + fatalError("The StarRating component must be initialised") + } - label.font = UIFont.preferredFont(forTextStyle: .headline) - label.numberOfLines = 1 - label.translatesAutoresizingMaskIntoConstraints = false - label.text = item.author - - return label + view.translatesAutoresizingMaskIntoConstraints = false + + return view }() - + + private lazy var authorView = { + guard let view = authorController.view else { + fatalError("The StarRating component must be initialised") + } + + view.translatesAutoresizingMaskIntoConstraints = false + + return view + }() + private lazy var commentLabel = { let label = UILabel() @@ -46,18 +68,65 @@ final class FeedItemViewController: UIViewController { return label }() + + private lazy var ratingView = { + let stack = UIStackView() + + stack.axis = .horizontal + stack.backgroundColor = .clear + stack.distribution = .fillProportionally + stack.translatesAutoresizingMaskIntoConstraints = false + + stack.addArrangedSubview(starRatingView) + stack.addArrangedSubview(appVersionView) - private lazy var ratingVersionLabel = { - let label = UILabel() + return stack + }() + + private lazy var scrollView = { + let scroll = UIScrollView() - label.font = UIFont.preferredFont(forTextStyle: .subheadline) - label.numberOfLines = 1 - label.translatesAutoresizingMaskIntoConstraints = false - label.text = item.rating.appVersion + scroll.backgroundColor = .clear + scroll.showsVerticalScrollIndicator = true + scroll.translatesAutoresizingMaskIntoConstraints = false - return label + return scroll }() + private lazy var stackView = { + let stack = UIStackView() + + stack.axis = .vertical + stack.alignment = .leading + stack.backgroundColor = .clear + stack.distribution = .fill + stack.spacing = 16 + stack.translatesAutoresizingMaskIntoConstraints = false + + return stack + }() + + private lazy var starRatingView = { + guard let view = starRatingController.view else { + fatalError("The StarRating component must be initialised") + } + + view.translatesAutoresizingMaskIntoConstraints = false + + return view + }() + + private lazy var titleLabel = { + let label = UILabel() + + label.font = UIFont.preferredFont(forTextStyle: .headline) + label.numberOfLines = 0 + label.translatesAutoresizingMaskIntoConstraints = false + label.text = item.title + + return label + }() + // MARK: Initialisers init(_ item: Review) { self.item = item @@ -68,14 +137,22 @@ final class FeedItemViewController: UIViewController { required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } - + // MARK: UIViewController override func viewDidLoad() { super.viewDidLoad() + addChild(appVersionController) + addChild(authorController) + addChild(starRatingController) + setView() setNavigationBar() setLayout() + + appVersionController.didMove(toParent: self) + authorController.didMove(toParent: self) + starRatingController.didMove(toParent: self) } } @@ -85,23 +162,31 @@ private extension FeedItemViewController { // MARK: Functions func setLayout() { + let scrollContentGuide = scrollView.contentLayoutGuide + let scrollFrameGuide = scrollView.frameLayoutGuide + NSLayoutConstraint.activate([ - authorLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 8), - authorLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -8), - authorLabel.topAnchor.constraint(equalTo: ratingVersionLabel.bottomAnchor, constant: 8), - authorLabel.heightAnchor.constraint(equalToConstant: 24), - commentLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 8), - commentLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -8), - commentLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 8), - commentLabel.heightAnchor.constraint(greaterThanOrEqualToConstant: 24), - ratingVersionLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 8), - ratingVersionLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -8), - ratingVersionLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 8), - ratingVersionLabel.heightAnchor.constraint(equalToConstant: 24), - titleLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 8), - titleLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -8), - titleLabel.topAnchor.constraint(equalTo: authorLabel.bottomAnchor, constant: 8), - titleLabel.heightAnchor.constraint(lessThanOrEqualToConstant: 72), + scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor), + scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + scrollView.topAnchor.constraint(equalTo: view.topAnchor), + scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + + stackView.bottomAnchor.constraint(equalTo: scrollContentGuide.bottomAnchor, constant: -16), + stackView.leadingAnchor.constraint(equalTo: scrollContentGuide.leadingAnchor), + stackView.topAnchor.constraint(equalTo: scrollContentGuide.topAnchor, constant: 8), + stackView.trailingAnchor.constraint(equalTo: scrollContentGuide.trailingAnchor), + stackView.leadingAnchor.constraint(equalTo: scrollFrameGuide.leadingAnchor), + stackView.trailingAnchor.constraint(equalTo: scrollFrameGuide.trailingAnchor), + + authorView.leadingAnchor.constraint(equalTo: stackView.leadingAnchor, constant: 16), + + ratingView.leadingAnchor.constraint(equalTo: stackView.leadingAnchor, constant: 16), + + titleLabel.leadingAnchor.constraint(equalTo: stackView.leadingAnchor, constant: 16), + titleLabel.trailingAnchor.constraint(equalTo: stackView.trailingAnchor, constant: -16), + + commentLabel.leadingAnchor.constraint(equalTo: stackView.leadingAnchor, constant: 16), + commentLabel.trailingAnchor.constraint(equalTo: stackView.trailingAnchor, constant: -16), ]) } @@ -109,16 +194,20 @@ private extension FeedItemViewController { navigationController?.navigationBar.prefersLargeTitles = true navigationController?.navigationBar.isTranslucent = true - navigationItem.title = "#\(String(item.id))" + navigationItem.title = "# \(String(item.id))" } func setView() { - view.backgroundColor = .white + view.backgroundColor = .systemBackground + + view.addSubview(scrollView) - view.addSubview(ratingVersionLabel) - view.addSubview(authorLabel) - view.addSubview(titleLabel) - view.addSubview(commentLabel) + scrollView.addSubview(stackView) + + stackView.addArrangedSubview(authorView) + stackView.addArrangedSubview(ratingView) + stackView.addArrangedSubview(titleLabel) + stackView.addArrangedSubview(commentLabel) } }