Skip to content

Commit d7fbef4

Browse files
authored
Merge branch 'main' into feature/Navigation_Home_ActivityDetails
2 parents 0079be7 + f544e90 commit d7fbef4

15 files changed

+229
-42
lines changed

solutions/devsprint-caio-santos-7/FinanceApp/AppDelegate/SceneDelegate.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
1515
guard let windowScene = (scene as? UIWindowScene) else { return }
1616

1717
self.window = UIWindow(frame: UIScreen.main.bounds)
18-
self.window?.rootViewController = UINavigationController(rootViewController: HomeViewController())
18+
self.window?.rootViewController = TabBarViewController()
1919
self.window?.windowScene = windowScene
2020
self.window?.makeKeyAndVisible()
2121
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import UIKit
2+
3+
extension UIColor {
4+
static func fromRGB(_ rgbValue: Int) -> UIColor! {
5+
return UIColor(
6+
red: CGFloat((Float((rgbValue & 0xff0000) >> 16)) / 255.0),
7+
green: CGFloat((Float((rgbValue & 0x00ff00) >> 8)) / 255.0),
8+
blue: CGFloat((Float((rgbValue & 0x0000ff) >> 0)) / 255.0),
9+
alpha: 1.0)
10+
}
11+
12+
convenience init?(hexString: String?) {
13+
let input: String! = (hexString ?? "")
14+
.replacingOccurrences(of: "#", with: "")
15+
.uppercased()
16+
var alpha: CGFloat = 1.0
17+
var red: CGFloat = 0
18+
var blue: CGFloat = 0
19+
var green: CGFloat = 0
20+
switch (input.count) {
21+
case 3 /* #RGB */:
22+
red = Self.colorComponent(from: input, start: 0, length: 1)
23+
green = Self.colorComponent(from: input, start: 1, length: 1)
24+
blue = Self.colorComponent(from: input, start: 2, length: 1)
25+
break
26+
case 4 /* #ARGB */:
27+
alpha = Self.colorComponent(from: input, start: 0, length: 1)
28+
red = Self.colorComponent(from: input, start: 1, length: 1)
29+
green = Self.colorComponent(from: input, start: 2, length: 1)
30+
blue = Self.colorComponent(from: input, start: 3, length: 1)
31+
break
32+
case 6 /* #RRGGBB */:
33+
red = Self.colorComponent(from: input, start: 0, length: 2)
34+
green = Self.colorComponent(from: input, start: 2, length: 2)
35+
blue = Self.colorComponent(from: input, start: 4, length: 2)
36+
break
37+
case 8 /* #AARRGGBB */:
38+
alpha = Self.colorComponent(from: input, start: 0, length: 2)
39+
red = Self.colorComponent(from: input, start: 2, length: 2)
40+
green = Self.colorComponent(from: input, start: 4, length: 2)
41+
blue = Self.colorComponent(from: input, start: 6, length: 2)
42+
break
43+
default:
44+
NSException.raise(NSExceptionName("Invalid color value"), format: "Color value \"%@\" is invalid. It should be a hex value of the form #RBG, #ARGB, #RRGGBB, or #AARRGGBB", arguments:getVaList([hexString ?? ""]))
45+
}
46+
self.init(red: red, green: green, blue: blue, alpha: alpha)
47+
}
48+
49+
static func colorComponent(from string: String!, start: Int, length: Int) -> CGFloat {
50+
let substring = (string as NSString)
51+
.substring(with: NSRange(location: start, length: length))
52+
let fullHex = length == 2 ? substring : "\(substring)\(substring)"
53+
var hexComponent: UInt64 = 0
54+
Scanner(string: fullHex)
55+
.scanHexInt64(&hexComponent)
56+
return CGFloat(Double(hexComponent) / 255.0)
57+
}
58+
}

solutions/devsprint-caio-santos-7/FinanceApp/Screens/ActivityDetails/ActivityCellView.swift

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,27 @@ import UIKit
1010
enum ActivityTypes: String {
1111
case mall = "Mall"
1212
case foodCourt = "Food Court"
13+
case oceanicAirlines = "Oceanic Airlines"
1314

1415
func getColor() -> UIColor {
1516
switch self {
1617
case .mall:
17-
return .red
18+
return UIColor(red: 190/255, green: 81/255, blue: 255/255, alpha: 1)
1819
case .foodCourt:
1920
return .blue
21+
case .oceanicAirlines:
22+
return .orange
23+
}
24+
}
25+
26+
func getIcon() -> UIImage? {
27+
switch self {
28+
case .mall:
29+
return UIImage(named: "bag.circle.fill")
30+
case .foodCourt:
31+
return UIImage(named: "fork.knife.circle.fill")
32+
case .oceanicAirlines:
33+
return UIImage(named: "airplane.circle.fill")
2034
}
2135
}
2236
}
@@ -72,6 +86,7 @@ class ActivityCellView: UITableViewCell {
7286

7387
if let type = ActivityTypes(rawValue: activity.name) {
7488
icon.tintColor = type.getColor()
89+
icon.image = type.getIcon()
7590
}
7691

7792
titleDescription.text = String.activityDetails(with: activity.price, and: activity.time)
@@ -96,22 +111,17 @@ extension ActivityCellView: ViewCodable {
96111

97112

98113
func setupConstraints() {
99-
100114
NSLayoutConstraint.activate([
101-
icon.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8),
115+
icon.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
102116
icon.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 8),
103117
icon.heightAnchor.constraint(equalToConstant: 48),
104118
icon.widthAnchor.constraint(equalToConstant: 48),
105119

106-
stackView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
120+
stackView.heightAnchor.constraint(greaterThanOrEqualToConstant: 48),
121+
stackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8),
122+
stackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -8),
107123
stackView.leadingAnchor.constraint(equalTo: icon.trailingAnchor, constant: 8),
108-
stackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -8),
109-
110-
titleLabel.leadingAnchor.constraint(equalTo: stackView.trailingAnchor),
111-
titleLabel.trailingAnchor.constraint(equalTo: stackView.trailingAnchor),
112-
113-
titleDescription.leadingAnchor.constraint(equalTo: titleLabel.leadingAnchor),
114-
titleDescription.trailingAnchor.constraint(equalTo: titleLabel.trailingAnchor),
124+
stackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -8)
115125
])
116126
}
117127
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//
2+
// ActivityListView.swift
3+
// FinanceApp
4+
//
5+
// Created by Mauricio on 18/10/22.
6+
//
7+
8+
import UIKit
9+
10+
class ActivityListView: UIView {
11+
private lazy var tableView: UITableView = {
12+
let tableView = UITableView(frame: .zero)
13+
tableView.translatesAutoresizingMaskIntoConstraints = false
14+
tableView.register(ActivityCellView.self, forCellReuseIdentifier: ActivityCellView.reuseIdentifier)
15+
tableView.separatorStyle = .none
16+
return tableView
17+
}()
18+
19+
override init(frame: CGRect) {
20+
super.init(frame: frame)
21+
self.configViews()
22+
self.buildHierarchy()
23+
self.setupConstraints()
24+
}
25+
26+
required init?(coder: NSCoder) {
27+
fatalError("init(coder:) has not been implemented")
28+
}
29+
30+
func reloadData() {
31+
tableView.reloadData()
32+
}
33+
34+
public func configTableViewProtocol(delegate: UITableViewDelegate,
35+
dataSource: UITableViewDataSource) {
36+
self.tableView.delegate = delegate
37+
self.tableView.dataSource = dataSource
38+
}
39+
}
40+
41+
extension ActivityListView: ViewCodable {
42+
func configViews (){
43+
backgroundColor = .white
44+
}
45+
46+
func buildHierarchy(){
47+
addSubview(tableView)
48+
}
49+
50+
func setupConstraints(){
51+
NSLayoutConstraint.activate([
52+
tableView.topAnchor.constraint(equalTo: self.topAnchor),
53+
tableView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
54+
tableView.trailingAnchor.constraint(equalTo: self.trailingAnchor),
55+
tableView.bottomAnchor.constraint(equalTo: self.bottomAnchor)
56+
])
57+
}
58+
}

solutions/devsprint-caio-santos-7/FinanceApp/Screens/Home/HomeView.swift

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,37 +9,33 @@ import UIKit
99

1010
protocol HomeViewDelegate: AnyObject {
1111
func showActivityDetails()
12+
func didSelectActivity()
1213
}
1314

1415
struct HomeViewConfiguration {
1516
let homeData: HomeData
1617
}
1718

1819
final class HomeView: UIView {
19-
20-
private let listViewCellIdentifier = "ListViewCellIdentifier"
21-
20+
21+
private var activities: [Activity] = []
2222
weak var delegate: HomeViewDelegate?
2323

24-
private var activities: [Activity] = []
25-
2624
private lazy var accountSummaryView: AccountSummaryView = {
2725
let element = AccountSummaryView()
2826
element.translatesAutoresizingMaskIntoConstraints = false
2927
return element
3028
}()
3129

32-
private lazy var tableView: UITableView = {
33-
let tableView = UITableView(frame: .zero)
34-
tableView.translatesAutoresizingMaskIntoConstraints = false
35-
tableView.register(UITableViewCell.self, forCellReuseIdentifier: self.listViewCellIdentifier)
36-
tableView.dataSource = self
37-
tableView.delegate = self
38-
return tableView
30+
private lazy var activityListView: ActivityListView = {
31+
let element = ActivityListView()
32+
element.translatesAutoresizingMaskIntoConstraints = false
33+
return element
3934
}()
40-
35+
4136
init() {
4237
super.init(frame: .zero)
38+
self.activityListView.configTableViewProtocol(delegate: self, dataSource: self)
4339
self.setupViews()
4440
}
4541

@@ -52,7 +48,7 @@ final class HomeView: UIView {
5248
accountSummaryView.updateValues(balance: configuration.homeData.balance,
5349
savings: configuration.homeData.savings,
5450
spending: configuration.homeData.spending)
55-
tableView.reloadData()
51+
activityListView.reloadData()
5652
}
5753
}
5854

@@ -66,7 +62,7 @@ private extension HomeView {
6662

6763
func configureSubviews() {
6864
addSubview(accountSummaryView)
69-
addSubview(tableView)
65+
addSubview(activityListView)
7066
}
7167

7268
func configureSubviewsConstraints() {
@@ -75,29 +71,36 @@ private extension HomeView {
7571
accountSummaryView.leadingAnchor.constraint(equalTo: safeAreaLayoutGuide.leadingAnchor, constant: 16),
7672
accountSummaryView.trailingAnchor.constraint(equalTo: safeAreaLayoutGuide.trailingAnchor, constant: -16),
7773

78-
tableView.topAnchor.constraint(equalTo: accountSummaryView.bottomAnchor, constant: 16),
79-
tableView.leadingAnchor.constraint(equalTo: safeAreaLayoutGuide.leadingAnchor),
80-
tableView.trailingAnchor.constraint(equalTo: safeAreaLayoutGuide.trailingAnchor),
81-
tableView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor)
74+
activityListView.topAnchor.constraint(equalTo: accountSummaryView.bottomAnchor, constant: 16),
75+
activityListView.leadingAnchor.constraint(equalTo: safeAreaLayoutGuide.leadingAnchor),
76+
activityListView.trailingAnchor.constraint(equalTo: safeAreaLayoutGuide.trailingAnchor),
77+
activityListView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor)
8278
])
8379
}
8480
}
8581

86-
//MARK: - Tableview
82+
//MARK: - Tableview
8783
extension HomeView: UITableViewDataSource, UITableViewDelegate {
8884
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
89-
return activities.count
85+
activities.count
9086
}
9187

9288
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
93-
let cell = tableView.dequeueReusableCell(withIdentifier: self.listViewCellIdentifier)!
94-
cell.textLabel?.text = activities[indexPath.row].name
89+
guard let cell: ActivityCellView = .createCell(for: tableView, at: indexPath),
90+
indexPath.row < activities.count else {
91+
return .init()
92+
}
93+
cell.updateValues(activity: activities[indexPath.row])
9594
return cell
9695
}
9796

9897
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
9998
delegate?.showActivityDetails()
10099
print("touched")
100+
//delegate?.didSelectActivity()
101+
}
102+
103+
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
104+
"Activity"
101105
}
102106
}
103-

solutions/devsprint-caio-santos-7/FinanceApp/Screens/Home/HomeViewController.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,7 @@ extension HomeViewController: HomeViewDelegate {
6464
navigationController?.pushViewController(vc, animated: true)
6565
}
6666

67-
67+
func didSelectActivity() {
68+
present(ContactListViewController(), animated: true)
69+
}
6870
}

solutions/devsprint-caio-santos-7/FinanceAppTests/Screens/ActivityDetails/ActivityCellViewTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ final class ActivityCellViewTests: XCTestCase {
3232
unwrappedSut.updateValues(activity: Activity(name: "TESTE TESTE TESTE TESTE TESTE TESTE TESTE",
3333
price: 0,
3434
time: "TESTE"))
35-
assertSnapshot(matching: unwrappedSut, as: .image)
35+
assertSnapshot(matching: unwrappedSut, as: .image(size: .init(width: UIScreen.main.bounds.width, height: 78)))
3636
}
3737

3838
func test_WhenInitActivityCellViewWithMall_ThenView_ShouldHaveValidSnapshot() throws {
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
//
2+
// ActivityListViewTests.swift
3+
// FinanceAppTests
4+
//
5+
// Created by Caio Santos on 18/10/22.
6+
//
7+
8+
import UIKit
9+
import SnapshotTesting
10+
import XCTest
11+
12+
@testable import FinanceApp
13+
14+
final class ActivityListViewTests: XCTestCase {
15+
16+
private var sut: ActivityListView?
17+
private var activities: [Activity] = [
18+
.init(name: "Test", price: 99, time: "Test"),
19+
.init(name: "Test", price: 99, time: "Test"),
20+
.init(name: "Test", price: 99, time: "Test"),
21+
.init(name: "Test", price: 99, time: "Test"),
22+
]
23+
24+
override func setUp() {
25+
// SnapshotTesting.isRecording = true
26+
sut = ActivityListView()
27+
}
28+
29+
func testRenderView() throws {
30+
let unwrappedSut = try XCTUnwrap(sut)
31+
unwrappedSut.configTableViewProtocol(delegate: self, dataSource: self)
32+
assertSnapshot(matching: unwrappedSut, as: .image(size: .init(width: UIScreen.main.bounds.width,
33+
height: 527)))
34+
}
35+
}
36+
37+
extension ActivityListViewTests: UITableViewDataSource, UITableViewDelegate {
38+
39+
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
40+
return activities.count
41+
}
42+
43+
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
44+
guard let cell: ActivityCellView = .createCell(for: tableView, at: indexPath),
45+
indexPath.row < activities.count else {
46+
return .init()
47+
}
48+
cell.updateValues(activity: activities[indexPath.row])
49+
return cell
50+
}
51+
52+
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
53+
"Activity"
54+
}
55+
}
56+

0 commit comments

Comments
 (0)