Skip to content

Commit 3db3dfe

Browse files
committed
Refactor views
1 parent b5fe2f1 commit 3db3dfe

File tree

5 files changed

+74
-51
lines changed

5 files changed

+74
-51
lines changed

ExampleMVVM/Presentation/MoviesScene/MovieDetails/View/MovieDetailsViewController.swift

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ final class MovieDetailsViewController: UIViewController, StoryboardInstantiable
1212

1313
@IBOutlet private var posterImageView: UIImageView!
1414
@IBOutlet private var overviewTextView: UITextView!
15-
15+
16+
// MARK: - Lifecicle
17+
1618
private var viewModel: MovieDetailsViewModel!
1719

1820
static func create(with viewModel: MovieDetailsViewModel) -> MovieDetailsViewController {
@@ -23,20 +25,25 @@ final class MovieDetailsViewController: UIViewController, StoryboardInstantiable
2325

2426
override func viewDidLoad() {
2527
super.viewDidLoad()
26-
28+
setupViews()
2729
bind(to: viewModel)
28-
view.accessibilityIdentifier = AccessibilityIdentifier.movieDetailsView
2930
}
3031

3132
private func bind(to viewModel: MovieDetailsViewModel) {
32-
title = viewModel.title
33-
overviewTextView.text = viewModel.overview
3433
viewModel.posterImage.observe(on: self) { [weak self] in self?.posterImageView.image = $0.flatMap(UIImage.init) }
35-
posterImageView.isHidden = viewModel.isPosterImageHidden
3634
}
3735

3836
override func viewDidLayoutSubviews() {
3937
super.viewDidLayoutSubviews()
4038
viewModel.updatePosterImage(width: Int(posterImageView.imageSizeAfterAspectFit.scaledSize.width))
4139
}
40+
41+
// MARK: - Private
42+
43+
private func setupViews() {
44+
title = viewModel.title
45+
overviewTextView.text = viewModel.overview
46+
posterImageView.isHidden = viewModel.isPosterImageHidden
47+
view.accessibilityIdentifier = AccessibilityIdentifier.movieDetailsView
48+
}
4249
}

ExampleMVVM/Presentation/MoviesScene/MoviesList/View/MoviesListTableView/MoviesListTableViewController.swift

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,36 +14,41 @@ final class MoviesListTableViewController: UITableViewController {
1414

1515
var viewModel: MoviesListViewModel!
1616

17+
// MARK: - Lifecicle
18+
1719
override func viewDidLoad() {
1820
super.viewDidLoad()
19-
tableView.estimatedRowHeight = MoviesListItemCell.height
20-
tableView.rowHeight = UITableView.automaticDimension
21-
bind(to: viewModel)
22-
}
23-
24-
private func bind(to viewModel: MoviesListViewModel) {
25-
viewModel.loadingType.observe(on: self) { [weak self] in self?.update(isLoadingNextPage: $0 == .nextPage) }
21+
setupViews()
2622
}
2723

2824
func reload() {
2925
tableView.reloadData()
3026
}
3127

32-
func update(isLoadingNextPage: Bool) {
33-
if isLoadingNextPage {
28+
func update(for loadingType: MoviesListViewModelLoading?) {
29+
switch loadingType {
30+
case .nextPage:
3431
nextPageLoadingSpinner?.removeFromSuperview()
3532
nextPageLoadingSpinner = UIActivityIndicatorView(style: .gray)
3633
nextPageLoadingSpinner?.startAnimating()
3734
nextPageLoadingSpinner?.isHidden = false
3835
nextPageLoadingSpinner?.frame = CGRect(x: CGFloat(0), y: CGFloat(0), width: tableView.frame.width, height: 44)
3936
tableView.tableFooterView = nextPageLoadingSpinner
40-
} else {
37+
case .fullScreen, .none:
4138
tableView.tableFooterView = nil
4239
}
4340
}
41+
42+
// MARK: - Private
43+
44+
private func setupViews() {
45+
tableView.estimatedRowHeight = MoviesListItemCell.height
46+
tableView.rowHeight = UITableView.automaticDimension
47+
}
4448
}
4549

4650
// MARK: - UITableViewDataSource, UITableViewDelegate
51+
4752
extension MoviesListTableViewController {
4853

4954
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
@@ -52,7 +57,8 @@ extension MoviesListTableViewController {
5257

5358
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
5459
guard let cell = tableView.dequeueReusableCell(withIdentifier: MoviesListItemCell.reuseIdentifier, for: indexPath) as? MoviesListItemCell else {
55-
fatalError("Cannot dequeue reusable cell \(MoviesListItemCell.self) with reuseIdentifier: \(MoviesListItemCell.reuseIdentifier)")
60+
assertionFailure("Cannot dequeue reusable cell \(MoviesListItemCell.self) with reuseIdentifier: \(MoviesListItemCell.reuseIdentifier)")
61+
return UITableViewCell()
5662
}
5763

5864
cell.fill(with: viewModel.items.value[indexPath.row],

ExampleMVVM/Presentation/MoviesScene/MoviesList/View/MoviesListViewController.swift

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -33,29 +33,30 @@ final class MoviesListViewController: UIViewController, StoryboardInstantiable,
3333

3434
override func viewDidLoad() {
3535
super.viewDidLoad()
36-
37-
title = viewModel.screenTitle
38-
emptyDataLabel.text = viewModel.emptyDataTitle
36+
setupViews()
3937
setupSearchController()
40-
addBehaviors([BackButtonEmptyTitleNavigationBarBehavior(),
41-
BlackStyleNavigationBarBehavior()])
42-
38+
setupBehaviours()
4339
bind(to: viewModel)
4440
viewModel.viewDidLoad()
4541
}
46-
42+
4743
private func bind(to viewModel: MoviesListViewModel) {
4844
viewModel.items.observe(on: self) { [weak self] _ in self?.moviesTableViewController?.reload() }
4945
viewModel.query.observe(on: self) { [weak self] in self?.updateSearchController(query: $0) }
5046
viewModel.error.observe(on: self) { [weak self] in self?.showError($0) }
51-
viewModel.loadingType.observe(on: self) { [weak self] _ in self?.updateViewsVisibility() }
47+
viewModel.loadingType.observe(on: self) { [weak self] in self?.updateViewsVisibility(loadingType: $0) }
5248
}
53-
49+
5450
override func viewWillDisappear(_ animated: Bool) {
5551
super.viewWillDisappear(animated)
5652
searchController.isActive = false
5753
}
5854

55+
private func updateSearchController(query: String) {
56+
searchController.isActive = false
57+
searchController.searchBar.text = query
58+
}
59+
5960
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
6061
if segue.identifier == String(describing: MoviesListTableViewController.self),
6162
let destinationVC = segue.destination as? MoviesListTableViewController {
@@ -67,37 +68,38 @@ final class MoviesListViewController: UIViewController, StoryboardInstantiable,
6768

6869
// MARK: - Private
6970

70-
private func updateSearchController(query: String) {
71-
searchController.isActive = false
72-
searchController.searchBar.text = query
71+
private func setupViews() {
72+
title = viewModel.screenTitle
73+
emptyDataLabel.text = viewModel.emptyDataTitle
74+
}
75+
76+
private func setupBehaviours() {
77+
addBehaviors([BackButtonEmptyTitleNavigationBarBehavior(),
78+
BlackStyleNavigationBarBehavior()])
7379
}
7480

7581
private func showError(_ error: String) {
7682
guard !error.isEmpty else { return }
7783
showAlert(title: viewModel.errorTitle, message: error)
7884
}
79-
80-
private func updateViewsVisibility() {
85+
86+
private func updateViewsVisibility(loadingType: MoviesListViewModelLoading?) {
8187
emptyDataLabel.isHidden = true
8288
moviesListContainer.isHidden = true
8389
suggestionsListContainer.isHidden = true
8490
LoadingView.hide()
8591

86-
switch viewModel.loadingType.value {
92+
switch loadingType {
8793
case .fullScreen: LoadingView.show()
8894
case .nextPage: moviesListContainer.isHidden = false
89-
case .none: updateMoviesListVisibility()
95+
case .none:
96+
moviesListContainer.isHidden = viewModel.isEmpty
97+
emptyDataLabel.isHidden = !viewModel.isEmpty
9098
}
99+
100+
moviesTableViewController?.update(for: loadingType)
91101
updateQueriesSuggestionsVisibility()
92102
}
93-
94-
private func updateMoviesListVisibility() {
95-
guard !viewModel.isEmpty else {
96-
emptyDataLabel.isHidden = false
97-
return
98-
}
99-
moviesListContainer.isHidden = false
100-
}
101103

102104
private func updateQueriesSuggestionsVisibility() {
103105
guard searchController.searchBar.isFirstResponder else {

ExampleMVVM/Presentation/MoviesScene/MoviesQueriesList/View/UIKit/MoviesQueriesTableViewController.swift

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ import UIKit
1010
final class MoviesQueriesTableViewController: UITableViewController, StoryboardInstantiable {
1111

1212
private var viewModel: MoviesQueryListViewModel!
13-
13+
14+
// MARK: - Lifecicle
15+
1416
static func create(with viewModel: MoviesQueryListViewModel) -> MoviesQueriesTableViewController {
1517
let view = MoviesQueriesTableViewController.instantiateViewController()
1618
view.viewModel = viewModel
@@ -19,11 +21,7 @@ final class MoviesQueriesTableViewController: UITableViewController, StoryboardI
1921

2022
override func viewDidLoad() {
2123
super.viewDidLoad()
22-
tableView.tableFooterView = UIView()
23-
tableView.backgroundColor = .clear
24-
tableView.estimatedRowHeight = MoviesQueriesItemCell.height
25-
tableView.rowHeight = UITableView.automaticDimension
26-
24+
setupViews()
2725
bind(to: viewModel)
2826
}
2927

@@ -32,10 +30,19 @@ final class MoviesQueriesTableViewController: UITableViewController, StoryboardI
3230
}
3331

3432
override func viewWillAppear(_ animated: Bool) {
35-
3633
super.viewWillAppear(animated)
34+
3735
viewModel.viewWillAppear()
3836
}
37+
38+
// MARK: - Private
39+
40+
private func setupViews() {
41+
tableView.tableFooterView = UIView()
42+
tableView.backgroundColor = .clear
43+
tableView.estimatedRowHeight = MoviesQueriesItemCell.height
44+
tableView.rowHeight = UITableView.automaticDimension
45+
}
3946
}
4047

4148
// MARK: - UITableViewDataSource, UITableViewDelegate
@@ -48,10 +55,11 @@ extension MoviesQueriesTableViewController {
4855

4956
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
5057
guard let cell = tableView.dequeueReusableCell(withIdentifier: MoviesQueriesItemCell.reuseIdentifier, for: indexPath) as? MoviesQueriesItemCell else {
51-
fatalError("Cannot dequeue reusable cell \(MoviesQueriesItemCell.self) with reuseIdentifier: \(MoviesQueriesItemCell.reuseIdentifier)")
58+
assertionFailure("Cannot dequeue reusable cell \(MoviesQueriesItemCell.self) with reuseIdentifier: \(MoviesQueriesItemCell.reuseIdentifier)")
59+
return UITableViewCell()
5260
}
5361
cell.fill(with: viewModel.items.value[indexPath.row])
54-
62+
5563
return cell
5664
}
5765

ExampleMVVM/Presentation/Utils/Observable.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public final class Observable<Value> {
3535

3636
private func notifyObservers() {
3737
for observer in observers {
38-
DispatchQueue.main.async { observer.block(self.value) }
38+
DispatchQueue.main.async { observer.block(self.value) }
3939
}
4040
}
4141
}

0 commit comments

Comments
 (0)