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

[GWL-316]: WorkoutEnvironmentViewController popGestgure 버그 수정 #321

Merged
merged 5 commits into from
Dec 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ final class WorkoutEnvironmentSetUpCoordinator: WorkoutEnvironmentSetUpCoordinat
let repository = WorkoutEnvironmentSetupNetworkRepository(session: URLSession.shared)

let useCase = WorkoutEnvironmentSetupUseCase(repository: repository)

let userInfoUseCase = UserInformationUseCase()

let viewModel = WorkoutEnvironmentSetupViewModel(
Expand All @@ -46,8 +47,9 @@ final class WorkoutEnvironmentSetUpCoordinator: WorkoutEnvironmentSetUpCoordinat
)

let viewController = WorkoutEnvironmentSetupViewController(viewModel: viewModel)
viewController.hidesBottomBarWhenPushed = true

navigationController.pushViewController(viewController, animated: false)
navigationController.pushViewController(viewController, animated: true)
}

func pushPeerRandomMatchingViewController(workoutSetting: WorkoutSetting) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ final class WorkoutSessionCoordinator: WorkoutSessionCoordinating {
let viewModel = CountDownBeforeWorkoutViewModel(coordinator: self, useCase: useCase)

let viewController = CountDownBeforeWorkoutViewController(viewModel: viewModel)
navigationController.pushViewController(viewController, animated: true)
navigationController.setViewControllers([viewController], animated: true)
}

func pushTapBarViewController() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,84 +31,104 @@ public final class WorkoutEnvironmentSetupViewController: UIViewController {
requestWorkoutPeerTypes.send()
}

var cancellables = Set<AnyCancellable>()
var viewModel: WorkoutEnvironmentSetupViewModelRepresentable?
private var subscriptions = Set<AnyCancellable>()
private let viewModel: WorkoutEnvironmentSetupViewModelRepresentable?

// MARK: - WorkoutEnvironmentSetupViewModelInput

let requestWorkoutTypes = PassthroughSubject<Void, Never>()
let requestWorkoutPeerTypes = PassthroughSubject<Void, Never>()
let selectWorkoutType = PassthroughSubject<WorkoutType?, Never>()
let selectPeerType = PassthroughSubject<PeerType?, Never>()
let endWorkoutEnvironment = PassthroughSubject<Void, Never>()
let didTapStartButton = PassthroughSubject<Void, Never>()
private let requestWorkoutTypes = PassthroughSubject<Void, Never>()
private let requestWorkoutPeerTypes = PassthroughSubject<Void, Never>()
private let selectWorkoutType = PassthroughSubject<WorkoutType?, Never>()
private let selectPeerType = PassthroughSubject<PeerType?, Never>()
private let endWorkoutEnvironment = PassthroughSubject<Void, Never>()
private let didTapStartButton = PassthroughSubject<Void, Never>()

// MARK: - ConatinerViewController Control Property

var workoutTypesDataSource: UICollectionViewDiffableDataSource<Int, WorkoutType>?
var workoutPeerTypesDataSource: UICollectionViewDiffableDataSource<Int, PeerType>?
private var workoutTypesDataSource: UICollectionViewDiffableDataSource<Int, WorkoutType>?
private var workoutPeerTypesDataSource: UICollectionViewDiffableDataSource<Int, PeerType>?

var workoutTypesCollectionView: UICollectionView?
var workoutPeerTypesCollectionView: UICollectionView?
private var workoutTypesCollectionView: UICollectionView?
private var workoutPeerTypesCollectionView: UICollectionView?

private let workoutSelectViewController = WorkoutSelectViewController()
private let workoutPeerSelectViewController = WorkoutPeerSelectViewController()
private lazy var contentViewControllers = [workoutSelectViewController, workoutPeerSelectViewController]
private var pageScrollView: UIScrollView? = nil

private let pageControl: GWPageControl = {
private let gwPageControl: GWPageControl = {
let pageControl = GWPageControl(count: Constant.countOfPage)

pageControl.translatesAutoresizingMaskIntoConstraints = false
return pageControl
}()

lazy var contentNavigationController = UINavigationController(rootViewController: workoutSelectViewController)
private lazy var pageViewController: UIPageViewController = {
let pageViewController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal)
pageViewController.dataSource = self
pageViewController.delegate = self

let scrollView = pageViewController.view.subviews
.compactMap { $0 as? UIScrollView }
.first
pageScrollView = scrollView
pageScrollView?.isScrollEnabled = false
pageScrollView?.delegate = self

pageViewController.view.translatesAutoresizingMaskIntoConstraints = false
return pageViewController
}()
}

private extension WorkoutEnvironmentSetupViewController {
func setup() {
view.backgroundColor = DesignSystemColor.primaryBackground
setupStyle()
setupViewHierarchyAndConstraints()
addNavigationGesture()
bind()

configureDataSource()
}

func setupStyle() {
navigationController?.isNavigationBarHidden = false
navigationController?.navigationBar.isHidden = false
Comment on lines +93 to +94
Copy link
Member

Choose a reason for hiding this comment

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

P3

두 개 차이가 뭔가요?!?!

navigationController?.navigationBar.tintColor = DesignSystemColor.main03

let titleBarButtonItemFont: UIFont = .preferredFont(forTextStyle: .title3, weight: .semibold)
navigationController?.tabBarItem.setTitleTextAttributes([.font: titleBarButtonItemFont], for: .normal)
view.backgroundColor = DesignSystemColor.primaryBackground
}

func setupViewHierarchyAndConstraints() {
let safeArea = view.safeAreaLayoutGuide

view.addSubview(pageControl)
pageControl.topAnchor.constraint(equalTo: safeArea.topAnchor, constant: 0).isActive = true
pageControl.leadingAnchor
view.addSubview(gwPageControl)
gwPageControl.topAnchor.constraint(equalTo: safeArea.topAnchor, constant: 0).isActive = true
gwPageControl.leadingAnchor
.constraint(equalTo: safeArea.leadingAnchor, constant: ConstraintsGuideLine.value + 11).isActive = true
pageControl.trailingAnchor
gwPageControl.trailingAnchor
.constraint(equalTo: safeArea.trailingAnchor, constant: -ConstraintsGuideLine.value).isActive = true
pageControl.heightAnchor.constraint(equalToConstant: 30).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
}
gwPageControl.heightAnchor.constraint(equalToConstant: 30).isActive = true

func addNavigationGesture() {
guard let recognizer = contentNavigationController.interactivePopGestureRecognizer else { return }
recognizer.delegate = self
recognizer.isEnabled = true
contentNavigationController.delegate = self
view.addSubview(pageViewController.view)
if let viewController = contentViewControllers.first {
pageViewController.setViewControllers([viewController], direction: .forward, animated: false)
}
pageViewController.view.leadingAnchor.constraint(equalTo: safeArea.leadingAnchor).isActive = true
pageViewController.view.trailingAnchor.constraint(equalTo: safeArea.trailingAnchor).isActive = true
pageViewController.view.topAnchor.constraint(equalTo: gwPageControl.bottomAnchor).isActive = true
pageViewController.view.bottomAnchor.constraint(equalTo: safeArea.bottomAnchor).isActive = true
}

func bind() {
workoutSelectViewController.delegate = self

workoutTypesCollectionView = workoutSelectViewController.workoutTypesCollectionView
workoutTypesCollectionView?.delegate = self

workoutPeerTypesCollectionView = workoutPeerSelectViewController.pearTypeSelectCollectionView
workoutPeerTypesCollectionView?.delegate = self

workoutSelectViewController.delegate = self

bindViewModel()
bindStartButton()
}
Expand All @@ -117,12 +137,12 @@ private extension WorkoutEnvironmentSetupViewController {
workoutPeerSelectViewController
.startButtonDidTapPublisher()
.bind(to: didTapStartButton)
.store(in: &cancellables)
.store(in: &subscriptions)
}

func bindViewModel() {
guard let viewModel else { return }
cancellables.removeAll()
subscriptions.removeAll()

let input = WorkoutEnvironmentSetupViewModelInput(
requestWorkoutTypes: requestWorkoutTypes.eraseToAnyPublisher(),
Expand All @@ -148,7 +168,7 @@ private extension WorkoutEnvironmentSetupViewController {
case let .didSelectWorkoutPeerType(bool): workoutPeerSelectViewController.startButtonEnable(bool)
}
}
.store(in: &cancellables)
.store(in: &subscriptions)
}

func configureDataSource() {
Expand Down Expand Up @@ -232,30 +252,48 @@ private extension WorkoutEnvironmentSetupViewController {
}
}

// MARK: UIGestureRecognizerDelegate

extension WorkoutEnvironmentSetupViewController: UIGestureRecognizerDelegate {
public func gestureRecognizerShouldBegin(_: UIGestureRecognizer) -> Bool {
return contentNavigationController.viewControllers.count > 1
// MARK: UIPageViewControllerDelegate, UIPageViewControllerDataSource

extension WorkoutEnvironmentSetupViewController: UIPageViewControllerDelegate, UIPageViewControllerDataSource {
public func pageViewController(
_ pageViewController: UIPageViewController,
didFinishAnimating _: Bool,
previousViewControllers _: [UIViewController],
transitionCompleted _: Bool
) {
if
let currentViewController = pageViewController.viewControllers?.first,
let currentIndex = contentViewControllers.firstIndex(of: currentViewController) {
pageScrollView?.isScrollEnabled = currentIndex == 0 ? false : true
gwPageControl.select(at: currentIndex)
}
}
}

// MARK: UINavigationControllerDelegate

extension WorkoutEnvironmentSetupViewController: UINavigationControllerDelegate {
public func navigationController(_: UINavigationController, didShow viewController: UIViewController, animated _: Bool) {
if viewController == workoutSelectViewController {
pageControl.select(at: 0)
public func pageViewController(_: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
guard
let viewControllerIndex = contentViewControllers.firstIndex(of: viewController),
viewControllerIndex - 1 >= 0
else {
return nil
}
let previousIndex = viewControllerIndex - 1
return contentViewControllers[previousIndex]
}

public func pageViewController(_: UIPageViewController, viewControllerAfter _: UIViewController) -> UIViewController? {
return nil
}
}

// MARK: WorkoutSelectViewDelegate

extension WorkoutEnvironmentSetupViewController: WorkoutSelectViewDelegate {
func nextButtonDidTap() {
pageControl.next()
contentNavigationController.pushViewController(workoutPeerSelectViewController, animated: true)
pageScrollView?.isScrollEnabled = false
gwPageControl.next()
pageViewController.setViewControllers([workoutPeerSelectViewController], direction: .forward, animated: true) { [weak self] _ in
self?.pageScrollView?.isScrollEnabled = true
}
Comment on lines +294 to +296
Copy link
Member

Choose a reason for hiding this comment

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

P3: setViewControllers로 하나의 view controller를 설정하게 되면 그 외 뷰 컨트롤러를 보여주지 못할 것 같은데요. 왼쪽으로 스와이프할 때 운동 선택화면으로 잘 넘어가지는지 궁금합니다.

Copy link
Member Author

Choose a reason for hiding this comment

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

넵 scrollView하게 되면 정상적으로 이전 화면을 보여주었습니다. 저도 과거 경험을 비추어 보면 setViewController는 한개의 뷰컨트롤러만 설정하는줄 알았는데 이전 화면도 반영되는 것을 확인하였습니다.

저도 이 PageViewController가 어떻게 작동하는지 너무 궁금하네요...

Copy link
Member

Choose a reason for hiding this comment

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

신기하네요.. 제가생각하는 setViewControllers와는 다른데요..? ㅋㅋㅋㅋ

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ protocol WorkoutSelectViewDelegate: AnyObject {
final class WorkoutSelectViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.setNavigationBarHidden(true, animated: false)
setupConstraints()
bind()
}
Expand All @@ -32,7 +31,7 @@ final class WorkoutSelectViewController: UIViewController {

private let workoutSelectDescriptionLabel: UILabel = {
let label = UILabel()
label.font = .preferredFont(forTextStyle: .title1, with: .traitBold)
label.font = .preferredFont(forTextStyle: .title1, weight: .bold)
label.textAlignment = .left
label.text = "1. 운동을 선택하세요"

Expand Down