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

박스오피스II [STEP 2] Erick, kyungmin #105

Open
wants to merge 24 commits into
base: ic_9_kyungmin
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
e0a51ed
♻️Refactor: errorAlert을 재사용하기 쉽도록 customAlert으로 수정
h-suo Aug 15, 2023
9414154
✨Feat: toolbar 세팅 및 barButton 생성
h-suo Aug 15, 2023
b757f78
🚚build: BoxOfficeCollectionViewListCell 리네임
YaRkyungmin Aug 15, 2023
77215c4
✨Feat: BoxOfficeCollectionViewGridCell 구현
YaRkyungmin Aug 15, 2023
12918c9
🩹Chore: listCell 리네임
YaRkyungmin Aug 15, 2023
bbd3ff2
✨Feat: girdLayout메서드 추가 및 CollectionViewMode타입 구현
YaRkyungmin Aug 15, 2023
57a4c8d
✨Feat: 아이콘 및 리스트 모드로 변경하는 로직 구현
h-suo Aug 15, 2023
7fd2e4d
✨Feat: Dynamic Type 적용
YaRkyungmin Aug 15, 2023
b91361c
♻️Refactor: AutoShrink 적용
h-suo Aug 15, 2023
5d124a0
✨Feat: MovieDetailScrollView 다이나믹 타입 적용
h-suo Aug 15, 2023
e555577
♻️Refactor: minimumScaleFactor 수정
h-suo Aug 15, 2023
97b8d2b
♻️Refactor: 텍스트 크기가 커져도 titleLabel이 생략되지 않도록 설정
h-suo Aug 15, 2023
c6b8118
🩹Chore: 매직스트링 네임스페이스 분리
YaRkyungmin Aug 15, 2023
37524cd
🩹Chore: gridLayout 그룹 높이 조정
YaRkyungmin Aug 15, 2023
1ba9a90
♻️Refactor: 화면 모드 변경 로직 수정
h-suo Aug 15, 2023
9243927
♻️Refactor: 영화 상세보기 화면에서는 toolbar가 안 보이도록 설정
h-suo Aug 15, 2023
30daee2
♻️Refactor: rankStackView의 기본 너비 재설정
h-suo Aug 15, 2023
869dd61
🐛Fix: BoxOfficeViewController로 돌아올때 Toolbar 보이게 설정
YaRkyungmin Aug 15, 2023
c852eb4
♻️Refactor: CollectionViewMode 주입
YaRkyungmin Aug 17, 2023
7869c80
♻️Refactor: UICollectionViewLayout을 인자로 받도록 변경
h-suo Aug 17, 2023
749c7d6
🩹Chore: 컨벤션 수정
YaRkyungmin Aug 17, 2023
c06bc43
♻️Refactor: gridCell contentView의 masksToBounds 설정
h-suo Aug 17, 2023
5997921
♻️Refactor: informationStackView 제약 수정
YaRkyungmin Aug 17, 2023
553f24b
📝Docs: II-Step2 README 작성
h-suo Aug 18, 2023
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
12 changes: 8 additions & 4 deletions BoxOffice.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
CD1AFC292A6E86B8001C50A7 /* BoxOfficeDataTransferObjectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1AFC282A6E86B8001C50A7 /* BoxOfficeDataTransferObjectTests.swift */; };
CD23029E2A78F2E5003B654C /* DailyBoxOffice.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD23029D2A78F2E5003B654C /* DailyBoxOffice.swift */; };
CD2302A02A78FC19003B654C /* UILabel+.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD23029F2A78FC19003B654C /* UILabel+.swift */; };
CD24DE742A77AF2C0076442B /* BoxOfficeCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD24DE732A77AF2C0076442B /* BoxOfficeCollectionViewCell.swift */; };
CD24DE742A77AF2C0076442B /* BoxOfficeCollectionViewListCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD24DE732A77AF2C0076442B /* BoxOfficeCollectionViewListCell.swift */; };
CD8284BC2A8B0DE3005145D0 /* BoxOfficeCollectionViewGridCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD8284BB2A8B0DE3005145D0 /* BoxOfficeCollectionViewGridCell.swift */; };
CD8564412A736C1500B5EFF8 /* URL+.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD8564402A736C1500B5EFF8 /* URL+.swift */; };
CDCCAEA32A79E44B008811C3 /* DataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDCCAEA22A79E44B008811C3 /* DataManager.swift */; };
CDDD7B032A70B8C700F471C8 /* NetworkManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDDD7B022A70B8C700F471C8 /* NetworkManager.swift */; };
Expand Down Expand Up @@ -90,7 +91,8 @@
CD1AFC2F2A6E8758001C50A7 /* BoxOffice.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = BoxOffice.xctestplan; sourceTree = "<group>"; };
CD23029D2A78F2E5003B654C /* DailyBoxOffice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DailyBoxOffice.swift; sourceTree = "<group>"; };
CD23029F2A78FC19003B654C /* UILabel+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UILabel+.swift"; sourceTree = "<group>"; };
CD24DE732A77AF2C0076442B /* BoxOfficeCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoxOfficeCollectionViewCell.swift; sourceTree = "<group>"; };
CD24DE732A77AF2C0076442B /* BoxOfficeCollectionViewListCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoxOfficeCollectionViewListCell.swift; sourceTree = "<group>"; };
CD8284BB2A8B0DE3005145D0 /* BoxOfficeCollectionViewGridCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoxOfficeCollectionViewGridCell.swift; sourceTree = "<group>"; };
CD8564402A736C1500B5EFF8 /* URL+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+.swift"; sourceTree = "<group>"; };
CDCCAEA22A79E44B008811C3 /* DataManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataManager.swift; sourceTree = "<group>"; };
CDCCAEA42A79ED04008811C3 /* API_KEY.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = API_KEY.xcconfig; sourceTree = "<group>"; };
Expand Down Expand Up @@ -217,7 +219,8 @@
CD1AFC1B2A6E776F001C50A7 /* View */ = {
isa = PBXGroup;
children = (
CD24DE732A77AF2C0076442B /* BoxOfficeCollectionViewCell.swift */,
CD24DE732A77AF2C0076442B /* BoxOfficeCollectionViewListCell.swift */,
CD8284BB2A8B0DE3005145D0 /* BoxOfficeCollectionViewGridCell.swift */,
CDEC11FE2A7E27F2000EC8FC /* MovieDetailScrollView.swift */,
);
path = View;
Expand Down Expand Up @@ -437,6 +440,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CD8284BC2A8B0DE3005145D0 /* BoxOfficeCollectionViewGridCell.swift in Sources */,
CDE52AAB2A81D29600183990 /* CacheManager.swift in Sources */,
CD2302A02A78FC19003B654C /* UILabel+.swift in Sources */,
CD23029E2A78F2E5003B654C /* DailyBoxOffice.swift in Sources */,
Expand All @@ -453,7 +457,7 @@
4541D5972A73953A00E6D276 /* DataError.swift in Sources */,
CDEC11FF2A7E27F2000EC8FC /* MovieDetailScrollView.swift in Sources */,
45BFE47B2A85EE6300342484 /* URLRequest+.swift in Sources */,
CD24DE742A77AF2C0076442B /* BoxOfficeCollectionViewCell.swift in Sources */,
CD24DE742A77AF2C0076442B /* BoxOfficeCollectionViewListCell.swift in Sources */,
63DF20EF2970E1A0005DF7D1 /* AppDelegate.swift in Sources */,
45BD07D12A7E70F6006B8467 /* PosterImageInformation.swift in Sources */,
63DF20F12970E1A0005DF7D1 /* SceneDelegate.swift in Sources */,
Expand Down
128 changes: 116 additions & 12 deletions BoxOffice/Controller/BoxOfficeViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import UIKit
final class BoxOfficeViewController: UIViewController {
private let boxOfficeManager: BoxOfficeManager
private var collectionView: UICollectionView!
private var collectionViewMode: CollectionViewMode = .list
Copy link

Choose a reason for hiding this comment

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

주입을 받아보는건 어떨까요 ?

Copy link
Author

Choose a reason for hiding this comment

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

주입시켜줬습니다:)

private var dailyBoxOfficeDataSource: UICollectionViewDiffableDataSource<Section, DailyBoxOffice>!
private let activityIndicator: UIActivityIndicatorView = {
let activityIndicator = UIActivityIndicatorView(style: .large)
Expand Down Expand Up @@ -37,13 +38,20 @@ final class BoxOfficeViewController: UIViewController {
configureUI()
setupConstraint()
}

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)

setupNavigation()
}
}

// MARK: setup Components
extension BoxOfficeViewController {
private func setupComponents() {
setupView()
setupNavigation()
setupToolbar()
setupCollectionView()
setupRefreshControl()
}
Expand All @@ -57,15 +65,33 @@ extension BoxOfficeViewController {

navigationItem.title = DateFormatter().dateString(from: boxOfficeManager.targetDate, with: DateFormatter.FormatCase.hyphen)
navigationItem.rightBarButtonItem = selectDateButton
navigationController?.setToolbarHidden(false, animated: false)
}

private func setupToolbar() {
let changeViewModeButton = UIBarButtonItem(title: NameSpace.changeMode, style: .plain, target: self, action: #selector(didTapChangeViewModeButton))
let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)

toolbarItems = [flexibleSpace, changeViewModeButton, flexibleSpace]
}

private func setupCollectionView() {
collectionView = UICollectionView(frame: .zero, collectionViewLayout: verticalLayout())
collectionView = UICollectionView(frame: .zero, collectionViewLayout: listLayout())
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.register(BoxOfficeCollectionViewCell.self, forCellWithReuseIdentifier: BoxOfficeCollectionViewCell.identifier)
collectionView.register(BoxOfficeCollectionViewListCell.self, forCellWithReuseIdentifier: BoxOfficeCollectionViewListCell.identifier)
collectionView.register(BoxOfficeCollectionViewGridCell.self, forCellWithReuseIdentifier: BoxOfficeCollectionViewGridCell.identifier)
collectionView.delegate = self
}

private func setupCollectionViewLayout() {
Copy link

Choose a reason for hiding this comment

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

인자로 안받고 이렇게 하신 이유가 있을까요 ?

Copy link

Choose a reason for hiding this comment

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

UICollectionViewDiffableDataSource 코드에서 분기처리를 한 것과 같이 collectionViewMode 프로퍼티를 이용하여 분기처리를 하려고 했었습니다!
UICollectionViewLayout을 인자로 받으면 코드가 더욱 간단해지기 때문에 인자로 받도록 변경하였습니다!

switch collectionViewMode {
case .list:
collectionView.setCollectionViewLayout(listLayout(), animated: true)
case .grid:
collectionView.setCollectionViewLayout(gridLayout(), animated: true)
}
}

private func setupRefreshControl() {
let refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action: #selector(fetchBoxOfficeData), for: .valueChanged)
Expand All @@ -85,7 +111,8 @@ extension BoxOfficeViewController {
boxOfficeManager.fetchBoxOffice { result in
if result == false {
DispatchQueue.main.async {
let alert = UIAlertController.errorAlert(NameSpace.fail, NameSpace.loadDataFail, actionTitle: NameSpace.check, actionType: .default)
let alertAction = UIAlertAction(title: NameSpace.check, style: .default)
let alert = UIAlertController.customAlert(alertTile: NameSpace.fail, alertMessage: NameSpace.loadDataFail, preferredStyle: .alert, alertActions: [alertAction])

self.collectionView.refreshControl?.endRefreshing()
self.activityIndicator.stopAnimating()
Expand Down Expand Up @@ -117,32 +144,87 @@ extension BoxOfficeViewController {
return
}
}

@objc private func didTapChangeViewModeButton() {
Copy link

Choose a reason for hiding this comment

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

LGTM :)

let action: UIAlertAction = {
switch collectionViewMode {
case .list:
return UIAlertAction(title: NameSpace.icon, style: .default) { [weak self] _ in
guard let self else {
return
}

self.collectionViewMode = .grid
self.setupCollectionViewLayout()
self.applyReloadSnapshot()
}
case .grid:
return UIAlertAction(title: NameSpace.list, style: .default) { [weak self] _ in
guard let self else {
return
}

self.collectionViewMode = .list
self.setupCollectionViewLayout()
self.applyReloadSnapshot()
}
}
}()

let cancelAction = UIAlertAction(title: NameSpace.cancel, style: .cancel)
let changeModeAlert = UIAlertController.customAlert(alertTile: NameSpace.selectMode, alertMessage: nil, preferredStyle: .actionSheet, alertActions: [action, cancelAction])

present(changeModeAlert, animated: true)
}
}

// MARK: CollectionView Layout
extension BoxOfficeViewController {
private func verticalLayout() -> UICollectionViewCompositionalLayout {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(0.1))
private func listLayout() -> UICollectionViewCompositionalLayout {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(80))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.2))
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(80))
let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitems: [item])
let section = NSCollectionLayoutSection(group: group)

return UICollectionViewCompositionalLayout(section: section)
}

private func gridLayout() -> UICollectionViewCompositionalLayout {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.5), heightDimension: .fractionalHeight(1.0))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
item.contentInsets = NSDirectionalEdgeInsets(top: 8, leading: 8, bottom: 8, trailing: 8)
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalWidth(0.5))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
group.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 8, bottom: 0, trailing: 8)
let section = NSCollectionLayoutSection(group: group)

return UICollectionViewCompositionalLayout(section: section)
}
}

// MARK: CollectionView DataSource
extension BoxOfficeViewController {
private func setupDataSource() {
dailyBoxOfficeDataSource = UICollectionViewDiffableDataSource<Section, DailyBoxOffice>(collectionView: collectionView) { collectionView, indexPath, dailyBoxOffice in
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: BoxOfficeCollectionViewCell.identifier, for: indexPath) as? BoxOfficeCollectionViewCell else {
return UICollectionViewCell()
switch self.collectionViewMode {
case .list:
guard let listCell = collectionView.dequeueReusableCell(withReuseIdentifier: BoxOfficeCollectionViewListCell.identifier, for: indexPath) as? BoxOfficeCollectionViewListCell else {
return UICollectionViewCell()
}

listCell.setupLabels(dailyBoxOffice)

return listCell
case .grid:
guard let gridCell = collectionView.dequeueReusableCell(withReuseIdentifier: BoxOfficeCollectionViewGridCell.identifier, for: indexPath) as? BoxOfficeCollectionViewGridCell else {
return UICollectionViewCell()
}

gridCell.setupLabels(dailyBoxOffice)

return gridCell
}

cell.setupLabels(dailyBoxOffice)

return cell
}
}
}
Expand All @@ -167,6 +249,15 @@ extension BoxOfficeViewController {

dailyBoxOfficeDataSource.apply(snapshot, animatingDifferences: true)
}

private func applyReloadSnapshot() {
var snapshot = NSDiffableDataSourceSnapshot<Section, DailyBoxOffice>()
snapshot.appendSections([.main])
snapshot.appendItems(boxOfficeManager.dailyBoxOffices, toSection: .main)
snapshot.reloadSections([.main])
Copy link

Choose a reason for hiding this comment

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

snapshot.reloadSections([.main])
이건 왜 필요한건가요 ?

Copy link

Choose a reason for hiding this comment

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

reloadSections(_:)snapshot의 지정된 섹션 내에서 데이터를 다시 로드하는 메서드입니다.
reloadSections를 하지 않으면 바뀐 데이터가 없어 apply를 하여도 셀이 바뀌지 않기 때문에 reloadSectionsmain 섹션의 데이터를 리로드하여 새로운 셀이 사용될 수 있도록 하였습니다!


dailyBoxOfficeDataSource.apply(snapshot, animatingDifferences: true)
}
}

// MARK: CalendarViewControllerDelegate
Expand Down Expand Up @@ -227,6 +318,11 @@ extension BoxOfficeViewController {
static let fail = "실패"
static let loadDataFail = "데이터 로드에 실패했습니다."
static let check = "확인"
static let changeMode = "화면 모드 변경"
static let icon = "아이콘"
static let list = "리스트"
static let cancel = "취소"
static let selectMode = "화면모드선택"
}
}

Expand All @@ -236,3 +332,11 @@ extension BoxOfficeViewController {
case main
}
}

// MARK: CollectionView Mode
extension BoxOfficeViewController {
Copy link

Choose a reason for hiding this comment

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

주입을 받을게 아니라면, private이여도 될 것 같네요.

Copy link
Author

Choose a reason for hiding this comment

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

주입을 받는 방식으로 바꿔줬기 때문에 private은 해주지 않았습니다☺️

private enum CollectionViewMode {
case list
case grid
}
}
10 changes: 6 additions & 4 deletions BoxOffice/Extension/UIAlertController+.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@

import UIKit

extension UIAlertController {
static func errorAlert(_ alertTitle: String?, _ alertMessage: String?, actionTitle: String?, actionType: UIAlertAction.Style) -> UIAlertController {
let alert = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: actionTitle, style: actionType))
extension UIAlertController {
static func customAlert(alertTile: String?, alertMessage: String?, preferredStyle: UIAlertController.Style, alertActions: [UIAlertAction]) -> UIAlertController {
let alert = UIAlertController(title: alertTile, message: alertMessage, preferredStyle: preferredStyle)
alertActions.forEach {
alert.addAction($0)
}

return alert
}
Expand Down
Loading