From 6fa8c895133fee38dcd2e89d3a590e8902022681 Mon Sep 17 00:00:00 2001 From: MaraMincho Date: Sun, 19 Nov 2023 11:20:26 +0900 Subject: [PATCH 01/12] =?UTF-8?q?feat:=20WorkoutPearTypeSelectCell=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...orkoutEnvironmentSetupViewController.swift | 8 +- .../View/WorkoutPearSelectCell.swift | 108 ++++++++++++++++++ .../WorkoutPearSelectViewController.swift | 21 ++++ .../View/WorkoutSelectViewController.swift | 14 +-- ...utCardCell.swift => WorkoutTypeCell.swift} | 14 +-- 5 files changed, 147 insertions(+), 18 deletions(-) create mode 100644 iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearSelectCell.swift create mode 100644 iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearSelectViewController.swift rename iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/{WorkoutCardCell.swift => WorkoutTypeCell.swift} (95%) diff --git a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift index b1b55dc7..dcf694b9 100644 --- a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift +++ b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift @@ -39,21 +39,21 @@ public final class WorkoutEnvironmentSetupViewController: UIViewController { }() var dataSource: UICollectionViewDiffableDataSource! - var workoutCardCollectionView: UICollectionView! + var workoutTypesCollectionView: UICollectionView! } private extension WorkoutEnvironmentSetupViewController { func setup() { view.backgroundColor = .systemBackground setupViewHierarchyAndConstraints() - workoutCardCollectionView = workoutSelectView.workoutCardCollectionView + workoutTypesCollectionView = workoutSelectView.workoutTypesCollectionView configureDataSource() } func configureDataSource() { - dataSource = .init(collectionView: workoutCardCollectionView, cellProvider: { collectionView, indexPath, _ in - let cell = collectionView.dequeueReusableCell(withReuseIdentifier: WorkoutCardCell.identifier, for: indexPath) + dataSource = .init(collectionView: workoutTypesCollectionView, cellProvider: { collectionView, indexPath, _ in + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: WorkoutTypeCell.identifier, for: indexPath) return cell }) } diff --git a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearSelectCell.swift b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearSelectCell.swift new file mode 100644 index 00000000..34ec5cba --- /dev/null +++ b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearSelectCell.swift @@ -0,0 +1,108 @@ +// +// WorkoutPearSelectCell.swift +// RecordFeature +// +// Created by MaraMincho on 11/19/23. +// Copyright © 2023 kr.codesquad.boostcamp8. All rights reserved. +// + +import DesignSystem +import UIKit + +// MARK: - WorkoutPearSelectCell + +final class WorkoutPearSelectCell: UICollectionViewCell { + static let identifier = "WorkoutPearSelectCell" + + // MARK: UI Components + + private let descriptionIcon: UIImageView = { + let imageFont: UIFont = .preferredFont(forTextStyle: .title1) + let configure = UIImage.SymbolConfiguration(font: imageFont) + let targetImage = UIImage(systemName: "person.3.fill", withConfiguration: configure) + + let imageView = UIImageView(image: targetImage) + imageView.contentMode = .scaleAspectFill + imageView.backgroundColor = DesignSystemColor.primaryBackGround + + imageView.contentMode = .scaleAspectFit + + imageView.translatesAutoresizingMaskIntoConstraints = false + return imageView + }() + + private let descriptionTitle: UILabel = { + let label = UILabel() + label.font = .preferredFont(forTextStyle: .title3) + label.text = "함께 운동을 진행합니다." + + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + private let titleDescription: UILabel = { + let label = UILabel() + label.font = .preferredFont(forTextStyle: .title3) + label.text = "함께 운동을 진행합니다." + + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + + private lazy var textStackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [ + descriptionTitle, + titleDescription, + ]) + stackView.alignment = .leading + stackView.axis = .vertical + stackView.spacing = 6 + + stackView.translatesAutoresizingMaskIntoConstraints = false + return stackView + }() + + private lazy var iconIncludeStackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [ + descriptionIcon, textStackView, + ]) + stackView.spacing = 12 + stackView.alignment = .leading + + stackView.translatesAutoresizingMaskIntoConstraints = false + return stackView + }() + + // MARK: - Initializations + + override init(frame: CGRect) { + super.init(frame: frame) + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + } + + private func setupHierarchyAndConstraints() { + contentView.addSubview(iconIncludeStackView) + iconIncludeStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true + iconIncludeStackView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true + + descriptionIcon.widthAnchor.constraint(equalToConstant: Metrics.iconWidth).isActive = true + descriptionIcon.heightAnchor.constraint(equalToConstant: Metrics.iconHeight).isActive = true + } +} + +// MARK: ParticipantsCollectionViewCell.Metrics + +private extension WorkoutPearSelectCell { + enum Metrics { + static let iconWidth: CGFloat = 60 + static let iconHeight: CGFloat = 42 + } + + enum Strings { + static let nicknameAccessibilityHint = "닉네임" + static let workoutDistanceAccessibilityHint = "운동한 거리" + } +} diff --git a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearSelectViewController.swift b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearSelectViewController.swift new file mode 100644 index 00000000..b21dc8a3 --- /dev/null +++ b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearSelectViewController.swift @@ -0,0 +1,21 @@ +// +// WorkoutPearSelectViewController.swift +// RecordFeature +// +// Created by MaraMincho on 11/19/23. +// Copyright © 2023 kr.codesquad.boostcamp8. All rights reserved. +// + +import UIKit + +final class WorkoutPearSelectViewController: UIViewController { + override func viewDidLoad() { + super.viewDidLoad() + + } + +} + +private extension WorkoutPearSelectViewController { + +} diff --git a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutSelectViewController.swift b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutSelectViewController.swift index a0aaf22a..76b056cd 100644 --- a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutSelectViewController.swift +++ b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutSelectViewController.swift @@ -28,9 +28,9 @@ final class WorkoutSelectViewController: UIViewController { return label }() - lazy var workoutCardCollectionView: UICollectionView = { + lazy var workoutTypesCollectionView: UICollectionView = { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: makeCollectionViewLayout()) - collectionView.register(WorkoutCardCell.self, forCellWithReuseIdentifier: WorkoutCardCell.identifier) + collectionView.register(WorkoutTypeCell.self, forCellWithReuseIdentifier: WorkoutTypeCell.identifier) collectionView.translatesAutoresizingMaskIntoConstraints = false return collectionView @@ -76,14 +76,14 @@ private extension WorkoutSelectViewController { workoutSelectDescriptionLabel.trailingAnchor .constraint(equalTo: safeArea.trailingAnchor, constant: -ConstraintsGuideLine.value).isActive = true - view.addSubview(workoutCardCollectionView) - workoutCardCollectionView.topAnchor + view.addSubview(workoutTypesCollectionView) + workoutTypesCollectionView.topAnchor .constraint(equalTo: workoutSelectDescriptionLabel.bottomAnchor, constant: 12).isActive = true - workoutCardCollectionView.leadingAnchor + workoutTypesCollectionView.leadingAnchor .constraint(equalTo: safeArea.leadingAnchor, constant: ConstraintsGuideLine.value).isActive = true - workoutCardCollectionView.trailingAnchor + workoutTypesCollectionView.trailingAnchor .constraint(equalTo: safeArea.trailingAnchor, constant: -ConstraintsGuideLine.value).isActive = true - workoutCardCollectionView.bottomAnchor + workoutTypesCollectionView.bottomAnchor .constraint(equalTo: view.bottomAnchor, constant: -15).isActive = true view.addSubview(nextButton) diff --git a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutCardCell.swift b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutTypeCell.swift similarity index 95% rename from iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutCardCell.swift rename to iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutTypeCell.swift index 8196eb54..388a0a2c 100644 --- a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutCardCell.swift +++ b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutTypeCell.swift @@ -1,5 +1,5 @@ // -// WorkoutCardCell.swift +// WorkoutTypeCell.swift // RecordFeature // // Created by MaraMincho on 11/16/23. @@ -9,10 +9,10 @@ import DesignSystem import UIKit -// MARK: - WorkoutCardCell +// MARK: - WorkoutTypeCell -class WorkoutCardCell: UICollectionViewCell { - static let identifier = "WorkoutCardCell" +class WorkoutTypeCell: UICollectionViewCell { + static let identifier = "WorkoutTypeCell" override init(frame: CGRect) { super.init(frame: frame) @@ -58,7 +58,7 @@ class WorkoutCardCell: UICollectionViewCell { } } -private extension WorkoutCardCell { +private extension WorkoutTypeCell { func setupConstraints() { contentView.addSubview(workoutIconDescriptionLabel) workoutIconDescriptionLabel.bottomAnchor @@ -94,7 +94,7 @@ private extension WorkoutCardCell { func makeSelectUI() { workoutIcon.tintColor = DesignSystemColor.main03 workoutIcon.makeShadow() - + workoutIconDescriptionLabel.textColor = DesignSystemColor.main03 workoutIconDescriptionLabel.font = .preferredFont(forTextStyle: .title3, with: .traitBold) } @@ -102,7 +102,7 @@ private extension WorkoutCardCell { func makeDeslectUI() { workoutIcon.tintColor = DesignSystemColor.primaryText workoutIcon.disableShadow() - + workoutIconDescriptionLabel.textColor = DesignSystemColor.primaryText workoutIconDescriptionLabel.font = .preferredFont(forTextStyle: .title3) } From acd79373023d39be403e9847d626996294d3e174 Mon Sep 17 00:00:00 2001 From: MaraMincho Date: Sun, 19 Nov 2023 12:10:09 +0900 Subject: [PATCH 02/12] =?UTF-8?q?feat:=20WorkoutViewController=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WorkoutPearSelectViewController.swift | 23 +++++++++++++++++-- ....swift => WorkoutPearTypeSelectCell.swift} | 4 ++-- 2 files changed, 23 insertions(+), 4 deletions(-) rename iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/{WorkoutPearSelectCell.swift => WorkoutPearTypeSelectCell.swift} (96%) diff --git a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearSelectViewController.swift b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearSelectViewController.swift index b21dc8a3..f715eccd 100644 --- a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearSelectViewController.swift +++ b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearSelectViewController.swift @@ -7,15 +7,34 @@ // import UIKit +import DesignSystem final class WorkoutPearSelectViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - + setup() } - + + private let startButton: UIButton = { + let button = UIButton() + button.configurationUpdateHandler = UIButton.Configuration.mainCircular(label: "출발") + + button.translatesAutoresizingMaskIntoConstraints = false + return button + }() } private extension WorkoutPearSelectViewController { + func setup() { + setHierarchyAndConstraints() + } + + func setHierarchyAndConstraints() { + let safeArea = view.safeAreaLayoutGuide + + view.addSubview(startButton) + startButton.bottomAnchor.constraint(equalTo: safeArea.bottomAnchor, constant: -50).isActive = true + startButton.centerXAnchor.constraint(equalTo: safeArea.centerXAnchor).isActive = true + } } diff --git a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearSelectCell.swift b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearTypeSelectCell.swift similarity index 96% rename from iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearSelectCell.swift rename to iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearTypeSelectCell.swift index 34ec5cba..963cfe2f 100644 --- a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearSelectCell.swift +++ b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearTypeSelectCell.swift @@ -11,7 +11,7 @@ import UIKit // MARK: - WorkoutPearSelectCell -final class WorkoutPearSelectCell: UICollectionViewCell { +final class WorkoutPearTypeSelectCell: UICollectionViewCell { static let identifier = "WorkoutPearSelectCell" // MARK: UI Components @@ -95,7 +95,7 @@ final class WorkoutPearSelectCell: UICollectionViewCell { // MARK: ParticipantsCollectionViewCell.Metrics -private extension WorkoutPearSelectCell { +private extension WorkoutPearTypeSelectCell { enum Metrics { static let iconWidth: CGFloat = 60 static let iconHeight: CGFloat = 42 From dbba487582864f2379752836bb6cac16ead08ff3 Mon Sep 17 00:00:00 2001 From: MaraMincho <103064352+MaraMincho@users.noreply.github.com> Date: Sun, 19 Nov 2023 22:13:29 +0900 Subject: [PATCH 03/12] =?UTF-8?q?feat:=20PageControll=20=EB=B2=84=EA=B7=B8?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...Cell.swift => WorkoutSelectTypeCell.swift} | 8 +-- .../Sources/ConstraintsGuideLine.swift | 1 + .../DesignSystem/Sources/GWPageConrol.swift | 70 +++++++++++-------- .../Sources/GWRoundShadowView.swift | 1 + 4 files changed, 47 insertions(+), 33 deletions(-) rename iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/{WorkoutTypeCell.swift => WorkoutSelectTypeCell.swift} (95%) diff --git a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutTypeCell.swift b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutSelectTypeCell.swift similarity index 95% rename from iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutTypeCell.swift rename to iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutSelectTypeCell.swift index 388a0a2c..d1ca63e6 100644 --- a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutTypeCell.swift +++ b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutSelectTypeCell.swift @@ -1,5 +1,5 @@ // -// WorkoutTypeCell.swift +// WorkoutSelectTypeCell.swift // RecordFeature // // Created by MaraMincho on 11/16/23. @@ -9,9 +9,9 @@ import DesignSystem import UIKit -// MARK: - WorkoutTypeCell +// MARK: - WorkoutSelectTypeCell -class WorkoutTypeCell: UICollectionViewCell { +class WorkoutSelectTypeCell: UICollectionViewCell { static let identifier = "WorkoutTypeCell" override init(frame: CGRect) { @@ -58,7 +58,7 @@ class WorkoutTypeCell: UICollectionViewCell { } } -private extension WorkoutTypeCell { +private extension WorkoutSelectTypeCell { func setupConstraints() { contentView.addSubview(workoutIconDescriptionLabel) workoutIconDescriptionLabel.bottomAnchor diff --git a/iOS/Projects/Shared/DesignSystem/Sources/ConstraintsGuideLine.swift b/iOS/Projects/Shared/DesignSystem/Sources/ConstraintsGuideLine.swift index f9e1f63d..5e23c966 100644 --- a/iOS/Projects/Shared/DesignSystem/Sources/ConstraintsGuideLine.swift +++ b/iOS/Projects/Shared/DesignSystem/Sources/ConstraintsGuideLine.swift @@ -10,4 +10,5 @@ import Foundation public enum ConstraintsGuideLine { public static let value: CGFloat = 23 + public static let secondaryValue: CGFloat = 23 } diff --git a/iOS/Projects/Shared/DesignSystem/Sources/GWPageConrol.swift b/iOS/Projects/Shared/DesignSystem/Sources/GWPageConrol.swift index 5c82baf7..671f51ce 100644 --- a/iOS/Projects/Shared/DesignSystem/Sources/GWPageConrol.swift +++ b/iOS/Projects/Shared/DesignSystem/Sources/GWPageConrol.swift @@ -7,7 +7,7 @@ // import Foundation - +import OSLog import UIKit // MARK: - GWPageControl @@ -16,7 +16,7 @@ public final class GWPageControl: UIView { let countOfPage: Int var currentPageIndex: Int = 0 let spacing: CGFloat = 8 - var pages: [GWRoundShadowView] = [] + var pages: [UIView] = [] var pageswidthConstraint: [NSLayoutConstraint] = [] // MARK: - 과연 UIVIew를 optional로 만드는게 맞을까? @@ -36,26 +36,13 @@ public final class GWPageControl: UIView { @available(*, unavailable) required init?(coder _: NSCoder) { - fatalError() - } - - private enum UIPageControlDefaultProperty { - static let numOfMinPage = 2 - static let numOfMaxPage = 5 - - static let range = numOfMaxPage ... numOfMaxPage - - static let selectedPageColor = DesignSystemColor.main03 - static let deselectedPageColor = DesignSystemColor.gray02 - - static let selectedPageWidth: CGFloat = 40 - static let deselectedPageWidth: CGFloat = 10 + fatalError("can not use initialization") } } private extension GWPageControl { func makePages() { - pages = (0 ..< countOfPage).enumerated().map { _, _ -> GWRoundShadowView in + pages = (0 ..< countOfPage).enumerated().map { _, _ -> UIView in return pageViewObject } } @@ -82,16 +69,12 @@ private extension GWPageControl { } } - var pageViewObject: GWRoundShadowView { - let view = GWRoundShadowView( - shadow: .init( - shadowColor: DesignSystemColor.gray02.cgColor, - shadowOffset: CGSize(width: 0, height: 1), - shadowOpacity: 0.2, shadowRadius: 4.0 - ), - cornerRadius: 4, - backgroundColor: DesignSystemColor.gray03.cgColor - ) + var pageViewObject: UIView { + let view = UIView() + view.layer.cornerRadius = 4 + view.clipsToBounds = true + view.backgroundColor = UIPageControlDefaultProperty.deselectedPageColor + view.layer.cornerCurve = .continuous view.translatesAutoresizingMaskIntoConstraints = false return view @@ -99,12 +82,28 @@ private extension GWPageControl { } public extension GWPageControl { + func makeNextPage() { + if currentPageIndex >= pages.count { + return + } + deselectPage(at: currentPageIndex) + currentPageIndex += 1 + selectPage(at: currentPageIndex) + + UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseInOut) { [weak self] in + guard let self else { return } + layoutIfNeeded() + } + } +} + +private extension GWPageControl { func selectPage(at pageIndex: Int) { guard 0 ..< pages.count ~= pageIndex else { return } let page = pages[pageIndex] - page.update(color: UIPageControlDefaultProperty.selectedPageColor) + page.backgroundColor = UIPageControlDefaultProperty.selectedPageColor let pageWidthConstraint = pageswidthConstraint[pageIndex] pageWidthConstraint.constant = UIPageControlDefaultProperty.selectedPageWidth @@ -115,9 +114,22 @@ public extension GWPageControl { return } let page = pages[pageIndex] - page.update(color: UIPageControlDefaultProperty.deselectedPageColor) + page.backgroundColor = UIPageControlDefaultProperty.deselectedPageColor let pageWidthConstraint = pageswidthConstraint[pageIndex] pageWidthConstraint.constant = UIPageControlDefaultProperty.deselectedPageWidth } + + private enum UIPageControlDefaultProperty { + static let numOfMinPage = 2 + static let numOfMaxPage = 5 + + static let range = numOfMaxPage ... numOfMaxPage + + static let selectedPageColor = DesignSystemColor.main03 + static let deselectedPageColor = DesignSystemColor.gray02 + + static let selectedPageWidth: CGFloat = 40 + static let deselectedPageWidth: CGFloat = 10 + } } diff --git a/iOS/Projects/Shared/DesignSystem/Sources/GWRoundShadowView.swift b/iOS/Projects/Shared/DesignSystem/Sources/GWRoundShadowView.swift index 0a6a0574..f85e96a4 100644 --- a/iOS/Projects/Shared/DesignSystem/Sources/GWRoundShadowView.swift +++ b/iOS/Projects/Shared/DesignSystem/Sources/GWRoundShadowView.swift @@ -10,6 +10,7 @@ import UIKit // MARK: - GWRoundShadowView +///애니메이션이 없는 뷰에서만 써야 합니다. public final class GWRoundShadowView: UIView { let containerView = UIView() let cornerRadius: CGFloat From 886194fb1b4b994392eea601101c6c595f0952bb Mon Sep 17 00:00:00 2001 From: MaraMincho <103064352+MaraMincho@users.noreply.github.com> Date: Sun, 19 Nov 2023 22:13:54 +0900 Subject: [PATCH 04/12] =?UTF-8?q?feat:=20=EB=B7=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...orkoutEnvironmentSetupViewController.swift | 27 +++- .../WorkoutPearSelectViewController.swift | 88 +++++++++++- .../View/WorkoutPearTypeSelectCell.swift | 131 ++++++++++++++---- .../View/WorkoutSelectTypeCell.swift | 2 +- .../View/WorkoutSelectViewController.swift | 35 ++++- 5 files changed, 240 insertions(+), 43 deletions(-) diff --git a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift index dcf694b9..63af130d 100644 --- a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift +++ b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift @@ -24,12 +24,13 @@ public final class WorkoutEnvironmentSetupViewController: UIViewController { } lazy var contentNAV: UINavigationController = { - let nav = UINavigationController(rootViewController: workoutSelectView) + let nav = UINavigationController(rootViewController: workoutSelectViewController) return nav }() - private let workoutSelectView = WorkoutSelectViewController() + private let workoutSelectViewController = WorkoutSelectViewController() + private let workoutPearSelectViewController = WorkoutPearSelectViewController() private let pageControl: GWPageControl = { let pageControl = GWPageControl(count: Constant.countOfPage) @@ -40,20 +41,27 @@ public final class WorkoutEnvironmentSetupViewController: UIViewController { var dataSource: UICollectionViewDiffableDataSource! var workoutTypesCollectionView: UICollectionView! + var workoutPaerTypesCollectionView: UICollectionView! } private extension WorkoutEnvironmentSetupViewController { + func bind() { + workoutTypesCollectionView = workoutSelectViewController.workoutTypesCollectionView + + workoutSelectViewController.delegate = self + } + func setup() { - view.backgroundColor = .systemBackground + view.backgroundColor = DesignSystemColor.primaryBackGround setupViewHierarchyAndConstraints() - workoutTypesCollectionView = workoutSelectView.workoutTypesCollectionView + bind() configureDataSource() } func configureDataSource() { dataSource = .init(collectionView: workoutTypesCollectionView, cellProvider: { collectionView, indexPath, _ in - let cell = collectionView.dequeueReusableCell(withReuseIdentifier: WorkoutTypeCell.identifier, for: indexPath) + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: WorkoutSelectTypeCell.identifier, for: indexPath) return cell }) } @@ -88,3 +96,12 @@ private extension WorkoutEnvironmentSetupViewController { static let countOfPage = 2 } } + +// MARK: WorkoutSelectViewDelegate + +extension WorkoutEnvironmentSetupViewController: WorkoutSelectViewDelegate { + func nextButtonDidTap() { + pageControl.makeNextPage() + contentNAV.pushViewController(workoutPearSelectViewController, animated: true) + } +} diff --git a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearSelectViewController.swift b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearSelectViewController.swift index f715eccd..0ce0bb3d 100644 --- a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearSelectViewController.swift +++ b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearSelectViewController.swift @@ -6,35 +6,111 @@ // Copyright © 2023 kr.codesquad.boostcamp8. All rights reserved. // -import UIKit import DesignSystem +import UIKit + +// MARK: - WorkoutPearSelectViewController final class WorkoutPearSelectViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() + view.backgroundColor = DesignSystemColor.primaryBackGround + setup() + + dataSource = .init(collectionView: pearTypeSelectCollectionView, cellProvider: { collectionView, indexPath, _ in + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: WorkoutPearTypeSelectCell.identifier, for: indexPath) + + return cell + }) + tempInitDataSource() } - + + var dataSource: UICollectionViewDiffableDataSource! + + private let workoutSelectDescriptionLabel: UILabel = { + let label = UILabel() + label.font = .preferredFont(forTextStyle: .title1, with: .traitBold) + label.textAlignment = .left + + label.text = "2. 누구랑 할까요?" + + label.translatesAutoresizingMaskIntoConstraints = false + return label + }() + private let startButton: UIButton = { let button = UIButton() button.configurationUpdateHandler = UIButton.Configuration.mainCircular(label: "출발") - + button.translatesAutoresizingMaskIntoConstraints = false return button }() + + lazy var pearTypeSelectCollectionView: UICollectionView = { + let collectionView = UICollectionView(frame: .zero, collectionViewLayout: makeCollectionViewLayout()) + collectionView.register(WorkoutPearTypeSelectCell.self, forCellWithReuseIdentifier: WorkoutPearTypeSelectCell.identifier) + collectionView.backgroundColor = .clear + + collectionView.translatesAutoresizingMaskIntoConstraints = false + return collectionView + }() } private extension WorkoutPearSelectViewController { + func makeCollectionViewLayout() -> UICollectionViewCompositionalLayout { + let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1))) + item.contentInsets = .init(top: Materics.itemInsets, leading: Materics.itemInsets, bottom: Materics.itemInsets, trailing: Materics.itemInsets) + + let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(0.15)) + let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitems: [item]) + + let section = NSCollectionLayoutSection(group: group) + + return UICollectionViewCompositionalLayout(section: section) + } + func setup() { setHierarchyAndConstraints() } - + func setHierarchyAndConstraints() { let safeArea = view.safeAreaLayoutGuide - + + view.addSubview(workoutSelectDescriptionLabel) + workoutSelectDescriptionLabel.topAnchor.constraint(equalTo: safeArea.topAnchor).isActive = true + workoutSelectDescriptionLabel.leadingAnchor + .constraint(equalTo: safeArea.leadingAnchor, constant: ConstraintsGuideLine.value).isActive = true + workoutSelectDescriptionLabel.trailingAnchor + .constraint(equalTo: safeArea.trailingAnchor, constant: -ConstraintsGuideLine.value).isActive = true + view.addSubview(startButton) startButton.bottomAnchor.constraint(equalTo: safeArea.bottomAnchor, constant: -50).isActive = true startButton.centerXAnchor.constraint(equalTo: safeArea.centerXAnchor).isActive = true + startButton.widthAnchor.constraint(equalToConstant: Materics.buttonHeight).isActive = true + startButton.heightAnchor.constraint(equalToConstant: Materics.buttonHeight).isActive = true + + view.addSubview(pearTypeSelectCollectionView) + pearTypeSelectCollectionView.topAnchor + .constraint(equalTo: workoutSelectDescriptionLabel.bottomAnchor, constant: 15).isActive = true + pearTypeSelectCollectionView.leadingAnchor + .constraint(equalTo: safeArea.leadingAnchor, constant: ConstraintsGuideLine.secondaryValue).isActive = true + pearTypeSelectCollectionView.trailingAnchor + .constraint(equalTo: safeArea.trailingAnchor, constant: -ConstraintsGuideLine.secondaryValue).isActive = true + pearTypeSelectCollectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true + } + + func tempInitDataSource() { + var snapshot = dataSource.snapshot() + snapshot.appendSections([0]) + snapshot.appendItems([.init(), .init(), .init()]) + dataSource.apply(snapshot) + } + + enum Materics { + static let buttonHeight: CGFloat = 150 + static let buttonWidth: CGFloat = 150 + + static let itemInsets: CGFloat = 9 } - } diff --git a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearTypeSelectCell.swift b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearTypeSelectCell.swift index 963cfe2f..99059cf0 100644 --- a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearTypeSelectCell.swift +++ b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearTypeSelectCell.swift @@ -1,5 +1,5 @@ // -// WorkoutPearSelectCell.swift +// WorkoutPearTypeSelectCell.swift // RecordFeature // // Created by MaraMincho on 11/19/23. @@ -9,11 +9,33 @@ import DesignSystem import UIKit -// MARK: - WorkoutPearSelectCell +// MARK: - WorkoutPearTypeSelectCell final class WorkoutPearTypeSelectCell: UICollectionViewCell { + // MARK: - Initializations + + override init(frame: CGRect) { + super.init(frame: frame) + setup() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + setup() + } + static let identifier = "WorkoutPearSelectCell" + override var isSelected: Bool { + didSet { + if isSelected { + makeSelectUI() + } else { + makeDeslectUI() + } + } + } + // MARK: UI Components private let descriptionIcon: UIImageView = { @@ -23,9 +45,8 @@ final class WorkoutPearTypeSelectCell: UICollectionViewCell { let imageView = UIImageView(image: targetImage) imageView.contentMode = .scaleAspectFill - imageView.backgroundColor = DesignSystemColor.primaryBackGround - imageView.contentMode = .scaleAspectFit + imageView.tintColor = DesignSystemColor.gray02 imageView.translatesAutoresizingMaskIntoConstraints = false return imageView @@ -34,16 +55,18 @@ final class WorkoutPearTypeSelectCell: UICollectionViewCell { private let descriptionTitle: UILabel = { let label = UILabel() label.font = .preferredFont(forTextStyle: .title3) - label.text = "함께 운동을 진행합니다." + label.text = "함께 하기" + label.textColor = DesignSystemColor.primaryText label.translatesAutoresizingMaskIntoConstraints = false return label }() - private let titleDescription: UILabel = { + private let descriptionSubTitle: UILabel = { let label = UILabel() - label.font = .preferredFont(forTextStyle: .title3) + label.font = .preferredFont(forTextStyle: .caption1) label.text = "함께 운동을 진행합니다." + label.textColor = DesignSystemColor.gray03 label.translatesAutoresizingMaskIntoConstraints = false return label @@ -52,7 +75,7 @@ final class WorkoutPearTypeSelectCell: UICollectionViewCell { private lazy var textStackView: UIStackView = { let stackView = UIStackView(arrangedSubviews: [ descriptionTitle, - titleDescription, + descriptionSubTitle, ]) stackView.alignment = .leading stackView.axis = .vertical @@ -72,37 +95,97 @@ final class WorkoutPearTypeSelectCell: UICollectionViewCell { stackView.translatesAutoresizingMaskIntoConstraints = false return stackView }() +} - // MARK: - Initializations - - override init(frame: CGRect) { - super.init(frame: frame) - } - - required init?(coder: NSCoder) { - super.init(coder: coder) +private extension WorkoutPearTypeSelectCell { + func setup() { + setupHierarchyAndConstraints() + setBackgroundColor() + makeShadowAndRounded() } - private func setupHierarchyAndConstraints() { + func setupHierarchyAndConstraints() { contentView.addSubview(iconIncludeStackView) - iconIncludeStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true + iconIncludeStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 12).isActive = true iconIncludeStackView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true descriptionIcon.widthAnchor.constraint(equalToConstant: Metrics.iconWidth).isActive = true descriptionIcon.heightAnchor.constraint(equalToConstant: Metrics.iconHeight).isActive = true } -} -// MARK: ParticipantsCollectionViewCell.Metrics + func setBackgroundColor() { + backgroundColor = DesignSystemColor.primaryBackGround + } + + func makeShadowAndRounded() { + let radius: CGFloat = 10 + contentView.layer.cornerRadius = radius + contentView.layer.borderWidth = 1 + contentView.layer.borderColor = UIColor.clear.cgColor + contentView.layer.masksToBounds = true + + layer.shadowColor = UIColor.black.cgColor + layer.shadowOffset = CGSize(width: 0, height: 1.0) + layer.shadowRadius = 2.0 + layer.shadowOpacity = 0.5 + layer.masksToBounds = false + layer.shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: radius).cgPath + layer.cornerRadius = radius + } + + func makeSelectUI() { + descriptionIcon.tintColor = DesignSystemColor.main03 + descriptionIcon.makeShadow() + + descriptionTitle.textColor = LabelProperty.selectdColor + descriptionTitle.font = LabelProperty.descriptionTitleDidSelectFont + + descriptionSubTitle.textColor = LabelProperty.selectdColor + descriptionSubTitle.font = LabelProperty.descriptionSubTitleDidSelectFont + } + + func makeDeslectUI() { + descriptionIcon.tintColor = LabelProperty.descriptionIconColor + descriptionIcon.disableShadow() + + descriptionTitle.textColor = LabelProperty.descriptionTitleTextColor + descriptionTitle.font = LabelProperty.descriptionTitleFont + + descriptionSubTitle.textColor = LabelProperty.descriptionSubTitleTextColor + descriptionSubTitle.font = LabelProperty.descriptionSubTitleFont + } -private extension WorkoutPearTypeSelectCell { enum Metrics { static let iconWidth: CGFloat = 60 static let iconHeight: CGFloat = 42 } - enum Strings { - static let nicknameAccessibilityHint = "닉네임" - static let workoutDistanceAccessibilityHint = "운동한 거리" + enum LabelProperty { + static let descriptionIconColor: UIColor = DesignSystemColor.gray02 + + static let descriptionTitleDidSelectFont: UIFont = .preferredFont(forTextStyle: .title3, with: .traitBold) + static let descriptionTitleFont: UIFont = .preferredFont(forTextStyle: .title3) + static let descriptionTitleTextColor: UIColor = DesignSystemColor.primaryText + + static let descriptionSubTitleFont: UIFont = .preferredFont(forTextStyle: .caption1) + static let descriptionSubTitleDidSelectFont: UIFont = .preferredFont(forTextStyle: .caption1, with: .traitBold) + static let descriptionSubTitleTextColor: UIColor = DesignSystemColor.gray03 + + static let selectdColor: UIColor = DesignSystemColor.main03 + } +} + +private extension UIImageView { + func makeShadow() { + layer.backgroundColor = UIColor.clear.cgColor + layer.shadowColor = UIColor.black.cgColor + layer.shadowOffset = CGSize(width: -2, height: 2) + layer.shadowRadius = 2.0 + layer.shadowOpacity = 0.3 + layer.masksToBounds = false + } + + func disableShadow() { + layer.shadowOpacity = 0 } } diff --git a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutSelectTypeCell.swift b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutSelectTypeCell.swift index d1ca63e6..473477a7 100644 --- a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutSelectTypeCell.swift +++ b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutSelectTypeCell.swift @@ -12,7 +12,7 @@ import UIKit // MARK: - WorkoutSelectTypeCell class WorkoutSelectTypeCell: UICollectionViewCell { - static let identifier = "WorkoutTypeCell" + static let identifier = "WorkoutTypeSelectCell" override init(frame: CGRect) { super.init(frame: frame) diff --git a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutSelectViewController.swift b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutSelectViewController.swift index 76b056cd..fa70d2c0 100644 --- a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutSelectViewController.swift +++ b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutSelectViewController.swift @@ -6,18 +6,30 @@ // Copyright © 2023 kr.codesquad.boostcamp8. All rights reserved. // +import Combine import DesignSystem +import TNCombineCocoa import UIKit +// MARK: - WorkoutSelectViewDelegate + +protocol WorkoutSelectViewDelegate: AnyObject { + func nextButtonDidTap() +} + // MARK: - WorkoutSelectViewController final class WorkoutSelectViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - setupConstraints() navigationController?.setNavigationBarHidden(true, animated: false) + setupConstraints() + bind() } + private var cancellables = Set() + weak var delegate: WorkoutSelectViewDelegate? + private let workoutSelectDescriptionLabel: UILabel = { let label = UILabel() label.font = .preferredFont(forTextStyle: .title1, with: .traitBold) @@ -30,7 +42,8 @@ final class WorkoutSelectViewController: UIViewController { lazy var workoutTypesCollectionView: UICollectionView = { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: makeCollectionViewLayout()) - collectionView.register(WorkoutTypeCell.self, forCellWithReuseIdentifier: WorkoutTypeCell.identifier) + collectionView.register(WorkoutSelectTypeCell.self, forCellWithReuseIdentifier: WorkoutSelectTypeCell.identifier) + collectionView.backgroundColor = UIColor.clear collectionView.translatesAutoresizingMaskIntoConstraints = false return collectionView @@ -51,10 +64,10 @@ private extension WorkoutSelectViewController { let item = NSCollectionLayoutItem(layoutSize: itemSize) item.contentInsets = .init( - top: Const.cellInsets, - leading: Const.cellInsets, - bottom: Const.cellInsets, - trailing: Const.cellInsets + top: Materics.cellInsets, + leading: Materics.cellInsets, + bottom: Materics.cellInsets, + trailing: Materics.cellInsets ) let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), @@ -95,7 +108,15 @@ private extension WorkoutSelectViewController { .constraint(equalTo: safeArea.bottomAnchor, constant: -28).isActive = true } - enum Const { + func bind() { + nextButton.publisher(.touchUpInside) + .sink { [weak self] _ in + self?.delegate?.nextButtonDidTap() + } + .store(in: &cancellables) + } + + enum Materics { static let cellInsets: CGFloat = 5 } } From 48d6f85d6ba128e5f1aa7cb5e4f05f191c47100b Mon Sep 17 00:00:00 2001 From: MaraMincho <103064352+MaraMincho@users.noreply.github.com> Date: Sun, 19 Nov 2023 22:39:59 +0900 Subject: [PATCH 05/12] =?UTF-8?q?feat:=20=EC=98=A4=ED=83=80=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20pear=20->=20peer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/WorkoutEnvironmentSetupViewController.swift | 4 ++-- ...r.swift => WorkoutPeerSelectViewController.swift} | 12 ++++++------ ...ectCell.swift => WorkoutPeerTypeSelectCell.swift} | 10 +++++----- .../DesignSystem/Sources/GWRoundShadowView.swift | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) rename iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/{WorkoutPearSelectViewController.swift => WorkoutPeerSelectViewController.swift} (91%) rename iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/{WorkoutPearTypeSelectCell.swift => WorkoutPeerTypeSelectCell.swift} (96%) diff --git a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift index 63af130d..2b986f86 100644 --- a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift +++ b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift @@ -30,7 +30,7 @@ public final class WorkoutEnvironmentSetupViewController: UIViewController { }() private let workoutSelectViewController = WorkoutSelectViewController() - private let workoutPearSelectViewController = WorkoutPearSelectViewController() + private let workoutPeerSelectViewController = WorkoutPeerSelectViewController() private let pageControl: GWPageControl = { let pageControl = GWPageControl(count: Constant.countOfPage) @@ -102,6 +102,6 @@ private extension WorkoutEnvironmentSetupViewController { extension WorkoutEnvironmentSetupViewController: WorkoutSelectViewDelegate { func nextButtonDidTap() { pageControl.makeNextPage() - contentNAV.pushViewController(workoutPearSelectViewController, animated: true) + contentNAV.pushViewController(workoutPeerSelectViewController, animated: true) } } diff --git a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearSelectViewController.swift b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPeerSelectViewController.swift similarity index 91% rename from iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearSelectViewController.swift rename to iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPeerSelectViewController.swift index 0ce0bb3d..9d9c35e2 100644 --- a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearSelectViewController.swift +++ b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPeerSelectViewController.swift @@ -1,5 +1,5 @@ // -// WorkoutPearSelectViewController.swift +// WorkoutPeerSelectViewController.swift // RecordFeature // // Created by MaraMincho on 11/19/23. @@ -9,9 +9,9 @@ import DesignSystem import UIKit -// MARK: - WorkoutPearSelectViewController +// MARK: - WorkoutPeerSelectViewController -final class WorkoutPearSelectViewController: UIViewController { +final class WorkoutPeerSelectViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = DesignSystemColor.primaryBackGround @@ -19,7 +19,7 @@ final class WorkoutPearSelectViewController: UIViewController { setup() dataSource = .init(collectionView: pearTypeSelectCollectionView, cellProvider: { collectionView, indexPath, _ in - let cell = collectionView.dequeueReusableCell(withReuseIdentifier: WorkoutPearTypeSelectCell.identifier, for: indexPath) + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: WorkoutPeerTypeSelectCell.identifier, for: indexPath) return cell }) @@ -49,7 +49,7 @@ final class WorkoutPearSelectViewController: UIViewController { lazy var pearTypeSelectCollectionView: UICollectionView = { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: makeCollectionViewLayout()) - collectionView.register(WorkoutPearTypeSelectCell.self, forCellWithReuseIdentifier: WorkoutPearTypeSelectCell.identifier) + collectionView.register(WorkoutPeerTypeSelectCell.self, forCellWithReuseIdentifier: WorkoutPeerTypeSelectCell.identifier) collectionView.backgroundColor = .clear collectionView.translatesAutoresizingMaskIntoConstraints = false @@ -57,7 +57,7 @@ final class WorkoutPearSelectViewController: UIViewController { }() } -private extension WorkoutPearSelectViewController { +private extension WorkoutPeerSelectViewController { func makeCollectionViewLayout() -> UICollectionViewCompositionalLayout { let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1))) item.contentInsets = .init(top: Materics.itemInsets, leading: Materics.itemInsets, bottom: Materics.itemInsets, trailing: Materics.itemInsets) diff --git a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearTypeSelectCell.swift b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPeerTypeSelectCell.swift similarity index 96% rename from iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearTypeSelectCell.swift rename to iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPeerTypeSelectCell.swift index 99059cf0..a8388d28 100644 --- a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPearTypeSelectCell.swift +++ b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPeerTypeSelectCell.swift @@ -1,5 +1,5 @@ // -// WorkoutPearTypeSelectCell.swift +// WorkoutPeerTypeSelectCell.swift // RecordFeature // // Created by MaraMincho on 11/19/23. @@ -9,9 +9,9 @@ import DesignSystem import UIKit -// MARK: - WorkoutPearTypeSelectCell +// MARK: - WorkoutPeerTypeSelectCell -final class WorkoutPearTypeSelectCell: UICollectionViewCell { +final class WorkoutPeerTypeSelectCell: UICollectionViewCell { // MARK: - Initializations override init(frame: CGRect) { @@ -24,7 +24,7 @@ final class WorkoutPearTypeSelectCell: UICollectionViewCell { setup() } - static let identifier = "WorkoutPearSelectCell" + static let identifier = "WorkoutPeerSelectCell" override var isSelected: Bool { didSet { @@ -97,7 +97,7 @@ final class WorkoutPearTypeSelectCell: UICollectionViewCell { }() } -private extension WorkoutPearTypeSelectCell { +private extension WorkoutPeerTypeSelectCell { func setup() { setupHierarchyAndConstraints() setBackgroundColor() diff --git a/iOS/Projects/Shared/DesignSystem/Sources/GWRoundShadowView.swift b/iOS/Projects/Shared/DesignSystem/Sources/GWRoundShadowView.swift index f85e96a4..72779f1c 100644 --- a/iOS/Projects/Shared/DesignSystem/Sources/GWRoundShadowView.swift +++ b/iOS/Projects/Shared/DesignSystem/Sources/GWRoundShadowView.swift @@ -10,7 +10,7 @@ import UIKit // MARK: - GWRoundShadowView -///애니메이션이 없는 뷰에서만 써야 합니다. +/// 차후 interaction을 통해 사이즈나 constarints가 달라진다면 쓸 수 없는 UIComponent입니다. public final class GWRoundShadowView: UIView { let containerView = UIView() let cornerRadius: CGFloat From 9f88d66ad54d121c54a01ee26c9b75336c19a374 Mon Sep 17 00:00:00 2001 From: MaraMincho <103064352+MaraMincho@users.noreply.github.com> Date: Mon, 20 Nov 2023 08:58:16 +0900 Subject: [PATCH 06/12] =?UTF-8?q?feat:=20pageControl=20move=20prev=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...orkoutEnvironmentSetupViewController.swift | 30 ++++++++++++++----- .../WorkoutPeerSelectViewController.swift | 16 +++++----- .../DesignSystem/Sources/GWPageConrol.swift | 14 +++++++++ .../Sources/GWRoundShadowView.swift | 1 - 4 files changed, 45 insertions(+), 16 deletions(-) diff --git a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift index 2b986f86..266fcc3a 100644 --- a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift +++ b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift @@ -23,7 +23,7 @@ public final class WorkoutEnvironmentSetupViewController: UIViewController { insertTempSource() } - lazy var contentNAV: UINavigationController = { + lazy var contentNavigationController: UINavigationController = { let nav = UINavigationController(rootViewController: workoutSelectViewController) return nav @@ -54,6 +54,7 @@ private extension WorkoutEnvironmentSetupViewController { func setup() { view.backgroundColor = DesignSystemColor.primaryBackGround setupViewHierarchyAndConstraints() + addNavigationGesture() bind() configureDataSource() @@ -84,12 +85,17 @@ private extension WorkoutEnvironmentSetupViewController { pageControl.trailingAnchor.constraint(equalTo: safeArea.trailingAnchor, constant: -23).isActive = true pageControl.heightAnchor.constraint(equalToConstant: 30).isActive = true - view.addSubview(contentNAV.view) - contentNAV.view.translatesAutoresizingMaskIntoConstraints = false - contentNAV.view.leadingAnchor.constraint(equalTo: safeArea.leadingAnchor).isActive = true - contentNAV.view.trailingAnchor.constraint(equalTo: safeArea.trailingAnchor).isActive = true - contentNAV.view.topAnchor.constraint(equalTo: pageControl.bottomAnchor).isActive = true - contentNAV.view.bottomAnchor.constraint(equalTo: safeArea.bottomAnchor).isActive = true + view.addSubview(contentNavigationController.view) + contentNavigationController.view.translatesAutoresizingMaskIntoConstraints = false + contentNavigationController.view.leadingAnchor.constraint(equalTo: safeArea.leadingAnchor).isActive = true + contentNavigationController.view.trailingAnchor.constraint(equalTo: safeArea.trailingAnchor).isActive = true + contentNavigationController.view.topAnchor.constraint(equalTo: pageControl.bottomAnchor).isActive = true + contentNavigationController.view.bottomAnchor.constraint(equalTo: safeArea.bottomAnchor).isActive = true + } + + func addNavigationGesture() { + contentNavigationController.interactivePopGestureRecognizer?.delegate = self + contentNavigationController.interactivePopGestureRecognizer?.isEnabled = true } enum Constant { @@ -97,11 +103,19 @@ private extension WorkoutEnvironmentSetupViewController { } } +// MARK: UIGestureRecognizerDelegate + +extension WorkoutEnvironmentSetupViewController: UIGestureRecognizerDelegate { + public func gestureRecognizerShouldBegin(_: UIGestureRecognizer) -> Bool { + return contentNavigationController.viewControllers.count > 1 + } +} + // MARK: WorkoutSelectViewDelegate extension WorkoutEnvironmentSetupViewController: WorkoutSelectViewDelegate { func nextButtonDidTap() { pageControl.makeNextPage() - contentNAV.pushViewController(workoutPeerSelectViewController, animated: true) + contentNavigationController.pushViewController(workoutPeerSelectViewController, animated: true) } } diff --git a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPeerSelectViewController.swift b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPeerSelectViewController.swift index 9d9c35e2..3d7a64c3 100644 --- a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPeerSelectViewController.swift +++ b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPeerSelectViewController.swift @@ -17,13 +17,6 @@ final class WorkoutPeerSelectViewController: UIViewController { view.backgroundColor = DesignSystemColor.primaryBackGround setup() - - dataSource = .init(collectionView: pearTypeSelectCollectionView, cellProvider: { collectionView, indexPath, _ in - let cell = collectionView.dequeueReusableCell(withReuseIdentifier: WorkoutPeerTypeSelectCell.identifier, for: indexPath) - - return cell - }) - tempInitDataSource() } var dataSource: UICollectionViewDiffableDataSource! @@ -51,6 +44,7 @@ final class WorkoutPeerSelectViewController: UIViewController { let collectionView = UICollectionView(frame: .zero, collectionViewLayout: makeCollectionViewLayout()) collectionView.register(WorkoutPeerTypeSelectCell.self, forCellWithReuseIdentifier: WorkoutPeerTypeSelectCell.identifier) collectionView.backgroundColor = .clear + collectionView.isScrollEnabled = false collectionView.translatesAutoresizingMaskIntoConstraints = false return collectionView @@ -72,6 +66,14 @@ private extension WorkoutPeerSelectViewController { func setup() { setHierarchyAndConstraints() + + dataSource = .init(collectionView: pearTypeSelectCollectionView, cellProvider: { collectionView, indexPath, _ in + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: WorkoutPeerTypeSelectCell.identifier, for: indexPath) + + return cell + }) + + tempInitDataSource() } func setHierarchyAndConstraints() { diff --git a/iOS/Projects/Shared/DesignSystem/Sources/GWPageConrol.swift b/iOS/Projects/Shared/DesignSystem/Sources/GWPageConrol.swift index 671f51ce..d03ef78c 100644 --- a/iOS/Projects/Shared/DesignSystem/Sources/GWPageConrol.swift +++ b/iOS/Projects/Shared/DesignSystem/Sources/GWPageConrol.swift @@ -95,6 +95,20 @@ public extension GWPageControl { layoutIfNeeded() } } + + func makePrev() { + if currentPageIndex >= pages.count { + return + } + deselectPage(at: currentPageIndex) + currentPageIndex -= 1 + selectPage(at: currentPageIndex) + + UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseInOut) { [weak self] in + guard let self else { return } + layoutIfNeeded() + } + } } private extension GWPageControl { diff --git a/iOS/Projects/Shared/DesignSystem/Sources/GWRoundShadowView.swift b/iOS/Projects/Shared/DesignSystem/Sources/GWRoundShadowView.swift index 72779f1c..3567fb34 100644 --- a/iOS/Projects/Shared/DesignSystem/Sources/GWRoundShadowView.swift +++ b/iOS/Projects/Shared/DesignSystem/Sources/GWRoundShadowView.swift @@ -26,7 +26,6 @@ public final class GWRoundShadowView: UIView { super.layoutSubviews() if shadowLayer == nil { shadowLayer = CAShapeLayer() - shadowLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).cgPath shadowLayer.fillColor = fillColor From c63d6c13c9bb5da585fc1ef1a3ca6a6d37f7950f Mon Sep 17 00:00:00 2001 From: MaraMincho <103064352+MaraMincho@users.noreply.github.com> Date: Mon, 20 Nov 2023 10:01:53 +0900 Subject: [PATCH 07/12] =?UTF-8?q?feat:=20gesture=20recognizer=EB=A5=BC=20?= =?UTF-8?q?=ED=86=B5=ED=95=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...WorkoutEnvironmentSetupViewController.swift | 18 +++++++++++------- .../DesignSystem/Sources/GWPageConrol.swift | 9 +++++++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift index 266fcc3a..e1373114 100644 --- a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift +++ b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift @@ -7,6 +7,7 @@ // import DesignSystem +import OSLog import UIKit // MARK: - WorkoutEnvironmentSetupViewController @@ -15,11 +16,6 @@ public final class WorkoutEnvironmentSetupViewController: UIViewController { override public func viewDidLoad() { super.viewDidLoad() setup() - } - - override public func viewDidAppear(_ animated: Bool) { - super.viewDidAppear(animated) - insertTempSource() } @@ -94,8 +90,16 @@ private extension WorkoutEnvironmentSetupViewController { } func addNavigationGesture() { - contentNavigationController.interactivePopGestureRecognizer?.delegate = self - contentNavigationController.interactivePopGestureRecognizer?.isEnabled = true + guard let recognizer = contentNavigationController.interactivePopGestureRecognizer else { return } + recognizer.addTarget(self, action: #selector(pageControlWithGesture)) + recognizer.delegate = self + recognizer.isEnabled = true + } + + @objc func pageControlWithGesture(gesture: UIGestureRecognizer) { + if gesture.state == .ended { + pageControl.makePrev() + } } enum Constant { diff --git a/iOS/Projects/Shared/DesignSystem/Sources/GWPageConrol.swift b/iOS/Projects/Shared/DesignSystem/Sources/GWPageConrol.swift index d03ef78c..5b9174fa 100644 --- a/iOS/Projects/Shared/DesignSystem/Sources/GWPageConrol.swift +++ b/iOS/Projects/Shared/DesignSystem/Sources/GWPageConrol.swift @@ -82,6 +82,15 @@ private extension GWPageControl { } public extension GWPageControl { + func makePage(index pageIndex: Int) { + if pageIndex >= pages.count { + return + } + deselectPage(at: currentPageIndex) + currentPageIndex = pageIndex + selectPage(at: currentPageIndex) + } + func makeNextPage() { if currentPageIndex >= pages.count { return From d2d546f6a5493b3623db9268fb077f6b51499428 Mon Sep 17 00:00:00 2001 From: MaraMincho <103064352+MaraMincho@users.noreply.github.com> Date: Mon, 20 Nov 2023 10:28:50 +0900 Subject: [PATCH 08/12] =?UTF-8?q?chor:=20=EC=98=A4=ED=83=80=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/WorkoutPeerSelectViewController.swift | 8 ++++---- .../View/WorkoutSelectViewController.swift | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPeerSelectViewController.swift b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPeerSelectViewController.swift index 3d7a64c3..b7a11f0e 100644 --- a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPeerSelectViewController.swift +++ b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPeerSelectViewController.swift @@ -54,7 +54,7 @@ final class WorkoutPeerSelectViewController: UIViewController { private extension WorkoutPeerSelectViewController { func makeCollectionViewLayout() -> UICollectionViewCompositionalLayout { let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1))) - item.contentInsets = .init(top: Materics.itemInsets, leading: Materics.itemInsets, bottom: Materics.itemInsets, trailing: Materics.itemInsets) + item.contentInsets = .init(top: Metrics.itemInsets, leading: Metrics.itemInsets, bottom: Metrics.itemInsets, trailing: Metrics.itemInsets) let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(0.15)) let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitems: [item]) @@ -89,8 +89,8 @@ private extension WorkoutPeerSelectViewController { view.addSubview(startButton) startButton.bottomAnchor.constraint(equalTo: safeArea.bottomAnchor, constant: -50).isActive = true startButton.centerXAnchor.constraint(equalTo: safeArea.centerXAnchor).isActive = true - startButton.widthAnchor.constraint(equalToConstant: Materics.buttonHeight).isActive = true - startButton.heightAnchor.constraint(equalToConstant: Materics.buttonHeight).isActive = true + startButton.widthAnchor.constraint(equalToConstant: Metrics.buttonHeight).isActive = true + startButton.heightAnchor.constraint(equalToConstant: Metrics.buttonHeight).isActive = true view.addSubview(pearTypeSelectCollectionView) pearTypeSelectCollectionView.topAnchor @@ -109,7 +109,7 @@ private extension WorkoutPeerSelectViewController { dataSource.apply(snapshot) } - enum Materics { + enum Metrics { static let buttonHeight: CGFloat = 150 static let buttonWidth: CGFloat = 150 diff --git a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutSelectViewController.swift b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutSelectViewController.swift index fa70d2c0..c080bf5a 100644 --- a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutSelectViewController.swift +++ b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutSelectViewController.swift @@ -64,10 +64,10 @@ private extension WorkoutSelectViewController { let item = NSCollectionLayoutItem(layoutSize: itemSize) item.contentInsets = .init( - top: Materics.cellInsets, - leading: Materics.cellInsets, - bottom: Materics.cellInsets, - trailing: Materics.cellInsets + top: Metrics.cellInsets, + leading: Metrics.cellInsets, + bottom: Metrics.cellInsets, + trailing: Metrics.cellInsets ) let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), @@ -116,7 +116,7 @@ private extension WorkoutSelectViewController { .store(in: &cancellables) } - enum Materics { + enum Metrics { static let cellInsets: CGFloat = 5 } } From 7d0acb65a97d84aeb0b4a5eb22eda740b5985f3e Mon Sep 17 00:00:00 2001 From: MaraMincho <103064352+MaraMincho@users.noreply.github.com> Date: Mon, 20 Nov 2023 17:16:18 +0900 Subject: [PATCH 09/12] =?UTF-8?q?feat:=20PageControl=20=EB=B2=84=EA=B7=B8?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...WorkoutEnvironmentSetupViewController.swift | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift index e1373114..e5fb528a 100644 --- a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift +++ b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift @@ -91,15 +91,9 @@ private extension WorkoutEnvironmentSetupViewController { func addNavigationGesture() { guard let recognizer = contentNavigationController.interactivePopGestureRecognizer else { return } - recognizer.addTarget(self, action: #selector(pageControlWithGesture)) recognizer.delegate = self recognizer.isEnabled = true - } - - @objc func pageControlWithGesture(gesture: UIGestureRecognizer) { - if gesture.state == .ended { - pageControl.makePrev() - } + contentNavigationController.delegate = self } enum Constant { @@ -115,6 +109,16 @@ extension WorkoutEnvironmentSetupViewController: UIGestureRecognizerDelegate { } } +// MARK: UINavigationControllerDelegate + +extension WorkoutEnvironmentSetupViewController: UINavigationControllerDelegate { + public func navigationController(_: UINavigationController, didShow viewController: UIViewController, animated _: Bool) { + if viewController == workoutSelectViewController { + pageControl.makePage(index: 0) + } + } +} + // MARK: WorkoutSelectViewDelegate extension WorkoutEnvironmentSetupViewController: WorkoutSelectViewDelegate { From 94ada26e2ecf2087ea073e9e2622f49476b7b3c7 Mon Sep 17 00:00:00 2001 From: MaraMincho <103064352+MaraMincho@users.noreply.github.com> Date: Mon, 20 Nov 2023 17:32:49 +0900 Subject: [PATCH 10/12] =?UTF-8?q?feat:=20backGround=20Color=20=EC=98=A4?= =?UTF-8?q?=ED=83=88=EC=9E=90=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/WorkoutEnvironmentSetupViewController.swift | 2 +- .../View/WorkoutPeerSelectViewController.swift | 2 +- .../WorkoutSelectScene/View/WorkoutPeerTypeSelectCell.swift | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift index e5fb528a..5a41078a 100644 --- a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift +++ b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift @@ -48,7 +48,7 @@ private extension WorkoutEnvironmentSetupViewController { } func setup() { - view.backgroundColor = DesignSystemColor.primaryBackGround + view.backgroundColor = DesignSystemColor.primaryBackground setupViewHierarchyAndConstraints() addNavigationGesture() bind() diff --git a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPeerSelectViewController.swift b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPeerSelectViewController.swift index b7a11f0e..5bc0eb28 100644 --- a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPeerSelectViewController.swift +++ b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPeerSelectViewController.swift @@ -14,7 +14,7 @@ import UIKit final class WorkoutPeerSelectViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - view.backgroundColor = DesignSystemColor.primaryBackGround + view.backgroundColor = DesignSystemColor.primaryBackground setup() } diff --git a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPeerTypeSelectCell.swift b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPeerTypeSelectCell.swift index a8388d28..0353e7bb 100644 --- a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPeerTypeSelectCell.swift +++ b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutPeerTypeSelectCell.swift @@ -114,7 +114,7 @@ private extension WorkoutPeerTypeSelectCell { } func setBackgroundColor() { - backgroundColor = DesignSystemColor.primaryBackGround + backgroundColor = DesignSystemColor.primaryBackground } func makeShadowAndRounded() { From 266744af40bc255c39afcecf91d47e85cf39fec6 Mon Sep 17 00:00:00 2001 From: MaraMincho <103064352+MaraMincho@users.noreply.github.com> Date: Mon, 20 Nov 2023 20:13:07 +0900 Subject: [PATCH 11/12] =?UTF-8?q?chore:=20Public=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...orkoutEnvironmentSetupViewController.swift | 4 +- .../DesignSystem/Sources/GWPageConrol.swift | 42 +++++++++---------- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift index 5a41078a..662b971b 100644 --- a/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift +++ b/iOS/Projects/Features/Record/Sources/WorkoutSelectScene/View/WorkoutEnvironmentSetupViewController.swift @@ -114,7 +114,7 @@ extension WorkoutEnvironmentSetupViewController: UIGestureRecognizerDelegate { extension WorkoutEnvironmentSetupViewController: UINavigationControllerDelegate { public func navigationController(_: UINavigationController, didShow viewController: UIViewController, animated _: Bool) { if viewController == workoutSelectViewController { - pageControl.makePage(index: 0) + pageControl.select(at: 0) } } } @@ -123,7 +123,7 @@ extension WorkoutEnvironmentSetupViewController: UINavigationControllerDelegate extension WorkoutEnvironmentSetupViewController: WorkoutSelectViewDelegate { func nextButtonDidTap() { - pageControl.makeNextPage() + pageControl.next() contentNavigationController.pushViewController(workoutPeerSelectViewController, animated: true) } } diff --git a/iOS/Projects/Shared/DesignSystem/Sources/GWPageConrol.swift b/iOS/Projects/Shared/DesignSystem/Sources/GWPageConrol.swift index 5b9174fa..f1d01b15 100644 --- a/iOS/Projects/Shared/DesignSystem/Sources/GWPageConrol.swift +++ b/iOS/Projects/Shared/DesignSystem/Sources/GWPageConrol.swift @@ -7,13 +7,12 @@ // import Foundation -import OSLog import UIKit // MARK: - GWPageControl public final class GWPageControl: UIView { - let countOfPage: Int + let numberOfPage: Int var currentPageIndex: Int = 0 let spacing: CGFloat = 8 var pages: [UIView] = [] @@ -21,9 +20,10 @@ public final class GWPageControl: UIView { // MARK: - 과연 UIVIew를 optional로 만드는게 맞을까? - /// 2 와 5 사이 숫자를 입력하세요 아닐경우 nil이 리턴됩니다. - public init(count: Int = 2) { - countOfPage = (UIPageControlDefaultProperty.range).contains(count) ? + /// init에서 만약 5보다 큰 수나 2보다 작은 수가 입력되는 경우 + /// page 갯수가 2개로 설정 됩니다. + public init(count: Int) { + numberOfPage = (UIPageControlDefaultProperty.range).contains(count) ? count : UIPageControlDefaultProperty.numOfMinPage @@ -31,7 +31,7 @@ public final class GWPageControl: UIView { makePages() makePageConstraints() - selectPage(at: 0) + updateSelectPage(at: 0) } @available(*, unavailable) @@ -42,9 +42,7 @@ public final class GWPageControl: UIView { private extension GWPageControl { func makePages() { - pages = (0 ..< countOfPage).enumerated().map { _, _ -> UIView in - return pageViewObject - } + pages = (0 ..< numberOfPage).map { _ in pageView } } func makePageConstraints() { @@ -69,7 +67,7 @@ private extension GWPageControl { } } - var pageViewObject: UIView { + private var pageView: UIView { let view = UIView() view.layer.cornerRadius = 4 view.clipsToBounds = true @@ -82,22 +80,22 @@ private extension GWPageControl { } public extension GWPageControl { - func makePage(index pageIndex: Int) { + func select(at pageIndex: Int) { if pageIndex >= pages.count { return } - deselectPage(at: currentPageIndex) + updateDeselectPage(at: currentPageIndex) currentPageIndex = pageIndex - selectPage(at: currentPageIndex) + updateSelectPage(at: currentPageIndex) } - func makeNextPage() { + func next() { if currentPageIndex >= pages.count { return } - deselectPage(at: currentPageIndex) + updateDeselectPage(at: currentPageIndex) currentPageIndex += 1 - selectPage(at: currentPageIndex) + updateSelectPage(at: currentPageIndex) UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseInOut) { [weak self] in guard let self else { return } @@ -105,13 +103,13 @@ public extension GWPageControl { } } - func makePrev() { - if currentPageIndex >= pages.count { + func back() { + if currentPageIndex >= pages.count || currentPageIndex <= 0 { return } - deselectPage(at: currentPageIndex) + updateDeselectPage(at: currentPageIndex) currentPageIndex -= 1 - selectPage(at: currentPageIndex) + updateSelectPage(at: currentPageIndex) UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseInOut) { [weak self] in guard let self else { return } @@ -121,7 +119,7 @@ public extension GWPageControl { } private extension GWPageControl { - func selectPage(at pageIndex: Int) { + func updateSelectPage(at pageIndex: Int) { guard 0 ..< pages.count ~= pageIndex else { return } @@ -132,7 +130,7 @@ private extension GWPageControl { pageWidthConstraint.constant = UIPageControlDefaultProperty.selectedPageWidth } - func deselectPage(at pageIndex: Int) { + func updateDeselectPage(at pageIndex: Int) { guard 0 ..< pages.count ~= pageIndex else { return } From b7b13409b8315357d890c2ace6188a636dbf3d9a Mon Sep 17 00:00:00 2001 From: MaraMincho <103064352+MaraMincho@users.noreply.github.com> Date: Mon, 20 Nov 2023 20:31:19 +0900 Subject: [PATCH 12/12] =?UTF-8?q?chore:=20GWPageControl=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=EC=9D=B4=EB=A6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DesignSystem/Sources/GWPageConrol.swift | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/iOS/Projects/Shared/DesignSystem/Sources/GWPageConrol.swift b/iOS/Projects/Shared/DesignSystem/Sources/GWPageConrol.swift index f1d01b15..d58a416b 100644 --- a/iOS/Projects/Shared/DesignSystem/Sources/GWPageConrol.swift +++ b/iOS/Projects/Shared/DesignSystem/Sources/GWPageConrol.swift @@ -27,7 +27,7 @@ public final class GWPageControl: UIView { count : UIPageControlDefaultProperty.numOfMinPage - super.init(frame: .init(origin: .zero, size: CGSize(width: 60, height: 10))) + super.init(frame: .zero) makePages() makePageConstraints() @@ -81,26 +81,25 @@ private extension GWPageControl { public extension GWPageControl { func select(at pageIndex: Int) { - if pageIndex >= pages.count { + if pageIndex >= pages.count || currentPageIndex <= 0 { return } updateDeselectPage(at: currentPageIndex) currentPageIndex = pageIndex updateSelectPage(at: currentPageIndex) + + startAnimation() } func next() { - if currentPageIndex >= pages.count { + if currentPageIndex >= pages.count || currentPageIndex <= 0 { return } updateDeselectPage(at: currentPageIndex) currentPageIndex += 1 updateSelectPage(at: currentPageIndex) - UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseInOut) { [weak self] in - guard let self else { return } - layoutIfNeeded() - } + startAnimation() } func back() { @@ -111,14 +110,18 @@ public extension GWPageControl { currentPageIndex -= 1 updateSelectPage(at: currentPageIndex) + startAnimation() + } +} + +private extension GWPageControl { + func startAnimation() { UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseInOut) { [weak self] in guard let self else { return } layoutIfNeeded() } } -} -private extension GWPageControl { func updateSelectPage(at pageIndex: Int) { guard 0 ..< pages.count ~= pageIndex else { return