Skip to content

Created the ActivityDetailsView screen #77

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

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

/* Begin PBXBuildFile section */
1DBC0432294176F6000501FA /* TabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DBC0431294176F6000501FA /* TabBarController.swift */; };
7EFE570B2947C06900CEB30C /* ActivityDetailsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EFE570A2947C06900CEB30C /* ActivityDetailsViewModel.swift */; };
98584A6D277E32C30028DBEA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98584A6C277E32C30028DBEA /* AppDelegate.swift */; };
98584A6F277E32C30028DBEA /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98584A6E277E32C30028DBEA /* SceneDelegate.swift */; };
98584A76277E32C50028DBEA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 98584A75277E32C50028DBEA /* Assets.xcassets */; };
Expand Down Expand Up @@ -51,6 +52,8 @@
98C8A4E327C819DE00A630ED /* Contact.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98C8A4E227C819DE00A630ED /* Contact.swift */; };
98C8A4E527C81A3F00A630ED /* TransferResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98C8A4E427C81A3F00A630ED /* TransferResult.swift */; };
98C8A4E727C81A9C00A630ED /* UserProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98C8A4E627C81A9C00A630ED /* UserProfile.swift */; };
FBB56216294777360060278D /* BaseViewHierarchy.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBB56215294777360060278D /* BaseViewHierarchy.swift */; };
FBB56219294778320060278D /* BaseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBB56218294778320060278D /* BaseView.swift */; };
CCDA8BF12947F08A00E5410D /* SnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = CCDA8BF02947F08A00E5410D /* SnapshotTesting */; };
/* End PBXBuildFile section */

Expand All @@ -73,6 +76,7 @@

/* Begin PBXFileReference section */
1DBC0431294176F6000501FA /* TabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarController.swift; sourceTree = "<group>"; };
7EFE570A2947C06900CEB30C /* ActivityDetailsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityDetailsViewModel.swift; sourceTree = "<group>"; };
98584A69277E32C30028DBEA /* FinanceApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FinanceApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
98584A6C277E32C30028DBEA /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
98584A6E277E32C30028DBEA /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -120,6 +124,8 @@
98C8A4E227C819DE00A630ED /* Contact.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Contact.swift; sourceTree = "<group>"; };
98C8A4E427C81A3F00A630ED /* TransferResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransferResult.swift; sourceTree = "<group>"; };
98C8A4E627C81A9C00A630ED /* UserProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfile.swift; sourceTree = "<group>"; };
FBB56215294777360060278D /* BaseViewHierarchy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseViewHierarchy.swift; sourceTree = "<group>"; };
FBB56218294778320060278D /* BaseView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseView.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -276,6 +282,7 @@
98C8A4E227C819DE00A630ED /* Contact.swift */,
98C8A4E427C81A3F00A630ED /* TransferResult.swift */,
98C8A4E627C81A9C00A630ED /* UserProfile.swift */,
FBB56215294777360060278D /* BaseViewHierarchy.swift */,
);
path = Models;
sourceTree = "<group>";
Expand Down Expand Up @@ -312,6 +319,7 @@
children = (
98584B0E277E605F0028DBEA /* ActivityDetailsView.swift */,
98584B0A277E605F0028DBEA /* ActivityDetailsViewController.swift */,
7EFE570A2947C06900CEB30C /* ActivityDetailsViewModel.swift */,
);
path = ActivityDetails;
sourceTree = "<group>";
Expand All @@ -328,6 +336,7 @@
98906BEC29392209001D1975 /* Components */ = {
isa = PBXGroup;
children = (
FBB56217294778170060278D /* Base */,
98906BED2939221B001D1975 /* AccountSummaryView.swift */,
98906BEF2939223C001D1975 /* ActivityCellView.swift */,
98906BF129392248001D1975 /* ActivityListView.swift */,
Expand All @@ -354,6 +363,14 @@
path = Extensions;
sourceTree = "<group>";
};
FBB56217294778170060278D /* Base */ = {
isa = PBXGroup;
children = (
FBB56218294778320060278D /* BaseView.swift */,
);
path = Base;
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
Expand Down Expand Up @@ -503,6 +520,7 @@
98C8A4E327C819DE00A630ED /* Contact.swift in Sources */,
98C8A4E527C81A3F00A630ED /* TransferResult.swift in Sources */,
98584AE8277E50430028DBEA /* TransfersViewController.swift in Sources */,
FBB56216294777360060278D /* BaseViewHierarchy.swift in Sources */,
98906BF42939225B001D1975 /* ContactCellView.swift in Sources */,
98584B14277E605F0028DBEA /* ActivityDetailsView.swift in Sources */,
98584AE7277E50430028DBEA /* TransfersView.swift in Sources */,
Expand All @@ -519,7 +537,9 @@
989627E027ADC2F60009A07F /* DebugViewController.swift in Sources */,
98584AA5277E35E90028DBEA /* HomeViewController.swift in Sources */,
98906BF229392248001D1975 /* ActivityListView.swift in Sources */,
FBB56219294778320060278D /* BaseView.swift in Sources */,
98584AED277E50430028DBEA /* UserProfileView.swift in Sources */,
7EFE570B2947C06900CEB30C /* ActivityDetailsViewModel.swift in Sources */,
98C8A4E127C8196100A630ED /* ActivityDetails.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// BaseViewHierarchy.swift
// FinanceApp
//
// Created by Kleiton Mendes on 12/12/22.
//

import UIKit

struct BaseViewHierarchy {
let parentView: UIView
let subViews: [UIView]

init(parentView: UIView, subViews: [UIView]) {
self.parentView = parentView
self.subViews = subViews
}

func makeHierarchy() {
if let stackView = parentView as? UIStackView {
for view in subViews {
stackView.addArrangedSubview(view)
}
} else {
for view in subViews {
parentView.addSubview(view)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"images" : [
{
"filename" : "mall.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,12 +1,135 @@
//
// ActivityDetailsView.swift
// FinanceApp
//
// Created by Rodrigo Borges on 30/12/21.
//

import UIKit

class ActivityDetailsView: UIView {

final class ActivityDetailsView: BaseView {

// MARK: - Private Properties UI

private lazy var mainStack: UIStackView = {
let stack = UIStackView()
stack.axis = .vertical
stack.distribution = .fillEqually

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aqui dá pra remover já que os componentes tem instrinsicContentSize

stack.translatesAutoresizingMaskIntoConstraints = false

return stack
}()

private lazy var productView: UIView = {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dá pra resumir com uma inicialização simples

let view = UIView()

return view
}()

private lazy var productValueView: UIView = {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mesma coisa

let view = UIView()

return view
}()

private lazy var productImage: UIImageView = {
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false

return imageView
}()

private lazy var productNameLabel: UILabel = {
let label = UILabel()
label.textAlignment = .center
label.font = UIFont.boldSystemFont(ofSize: 17)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dá pra salvar o tamanho da fonte numa constante

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Outra coisa: Se a label comportar conteúdo grande, bom setar o número de linhas como zero.

label.translatesAutoresizingMaskIntoConstraints = false

return label
}()

private lazy var categoryNameLabel: UILabel = {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mesma coisa aqui

let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false

return label
}()

private lazy var productValue: UILabel = {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renomear pra productValueLabel

let label = UILabel()
label.font = UIFont.boldSystemFont(ofSize: 34)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Salvar em constantes

label.translatesAutoresizingMaskIntoConstraints = false

return label
}()

private lazy var purchaseTime: UILabel = {
let label = UILabel()
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false

return label
}()

private lazy var reportButton: UIButton = {
let button = UIButton()
button.layer.cornerRadius = 14

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Salvar em Constants

button.backgroundColor = .systemBlue

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acho que seria bom usar a classe de botão que o Thyago criou.

button.setTitle("Report a issue", for: .normal)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Salvar a string numa constante

button.translatesAutoresizingMaskIntoConstraints = false

return button
}()

override var hierarchies: [BaseViewHierarchy] {
return [BaseViewHierarchy.init(parentView: self, subViews: [mainStack, reportButton]),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OBS: Não precisa do return

BaseViewHierarchy.init(parentView: mainStack, subViews: [productView, productValueView]),
BaseViewHierarchy.init(parentView: productView, subViews: [productImage, productNameLabel,categoryNameLabel]),
BaseViewHierarchy.init(parentView: productValueView, subViews: [productValue, purchaseTime])]
}

override var constraints: [NSLayoutConstraint] {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Salvar as constantes das constraints em Constants

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pular linha e deixar um comentário pra cada componente que adiciona constraints.

[
mainStack.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor),
mainStack.leadingAnchor.constraint(equalTo: leadingAnchor),
mainStack.trailingAnchor.constraint(equalTo: trailingAnchor),
mainStack.bottomAnchor.constraint(equalTo: reportButton.topAnchor, constant: -50),

productImage.centerXAnchor.constraint(equalTo: centerXAnchor),

productNameLabel.centerXAnchor.constraint(equalTo: centerXAnchor),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sempre é bom colocar além do centro da label os limites.

productNameLabel.topAnchor.constraint(equalTo: productImage.bottomAnchor, constant: 8),

categoryNameLabel.centerXAnchor.constraint(equalTo: centerXAnchor),
categoryNameLabel.topAnchor.constraint(equalTo: productNameLabel.bottomAnchor, constant: 8),

productValue.centerXAnchor.constraint(equalTo: centerXAnchor),
purchaseTime.centerXAnchor.constraint(equalTo: centerXAnchor),
purchaseTime.topAnchor.constraint(equalTo: productValue.bottomAnchor, constant: 8),

reportButton.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20),
reportButton.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor, constant: -15),
reportButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20),
reportButton.heightAnchor.constraint(equalToConstant: 56)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

O botão poderia ter um intrinsicContentSize.

]
}

private let viewModel: ActivityDetailsViewModel

// MARK: - Init

init(viewModel: ActivityDetailsViewModel) {
self.viewModel = viewModel
super.init(frame: .zero)
setupExtra()
}

@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

// MARK: - Private Methods

private func setupExtra() {
backgroundColor = .systemBackground
productImage.image = viewModel.image
productNameLabel.text = viewModel.name
categoryNameLabel.text = viewModel.category
productValue.text = viewModel.value
purchaseTime.text = viewModel.purchaseTime
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
//
// ActivityDetailsViewController.swift
// FinanceApp
//
// Created by Rodrigo Borges on 30/12/21.
//

import UIKit

class ActivityDetailsViewController: UIViewController {
final class ActivityDetailsViewController: UIViewController {

// MARK: - Life Cycle

override func loadView() {
self.view = ActivityDetailsView()
view = ActivityDetailsView(viewModel: ActivityDetailsViewModel(image: UIImage(named: "mall"),
name: "Mall",
category: "Shopping",
value: "$1000.0",
purchaseTime: "8:40"))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import UIKit

struct ActivityDetailsViewModel {
let image: UIImage?
let name: String
let category: String
let value: String
let purchaseTime: String
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// BaseView.swift
// FinanceApp
//
// Created by Kleiton Mendes on 12/12/22.
//

import UIKit

class BaseView: UIView {
open var hierarchies: [BaseViewHierarchy] { [] }

override init(frame: CGRect) {
super.init(frame: frame)
setupView()
setupConstraints()
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

private func setupConstraints() {
NSLayoutConstraint.activate(constraints)
}

private func setupView() {
for relation in hierarchies {
relation.makeHierarchy()
}
}
}