diff --git a/StreetDrop/StreetDrop/Presentation/MyPage/View/MyPageViewController.swift b/StreetDrop/StreetDrop/Presentation/MyPage/View/MyPageViewController.swift index 6bf2b00..0b838b5 100644 --- a/StreetDrop/StreetDrop/Presentation/MyPage/View/MyPageViewController.swift +++ b/StreetDrop/StreetDrop/Presentation/MyPage/View/MyPageViewController.swift @@ -20,7 +20,6 @@ final class MyPageViewController: UIViewController, Toastable, Alertable { private var stickyTopDimmedView: UIView? private lazy var musicDataSource: MusicDataSource = configureMusicDataSource() - private var myMusicType: MyMusicType = .drop private var collectionViewHeightConstraint: Constraint? private var viewModel: MyPageViewModel @@ -57,7 +56,6 @@ final class MyPageViewController: UIViewController, Toastable, Alertable { private lazy var scrollView: UIScrollView = { let scrollView = UIScrollView() scrollView.backgroundColor = UIColor.gray900 - scrollView.delegate = self return scrollView }() @@ -420,7 +418,7 @@ private extension MyPageViewController { return dimmedView } - func createTapListStackView() -> UIStackView { + func createTapListStackView(with type: MyMusicType) -> UIStackView { let newStackView = UIStackView() newStackView.axis = .horizontal newStackView.spacing = 8 @@ -435,7 +433,7 @@ private extension MyPageViewController { newLikeButton.setTitle("좋아요", for: .normal) newLikeButton.titleLabel?.font = .pretendard(size: 20, weightName: .bold) - if myMusicType == .like { + if type == .like { newDropButton.setTitleColor(UIColor.gray400, for: .normal) newDropButton.setTitleColor(UIColor(hexString: "#43464B"), for: .highlighted) @@ -452,7 +450,7 @@ private extension MyPageViewController { let newLabel = UILabel() newLabel.textColor = UIColor.gray400 newLabel.font = .pretendard(size: 14, weightName: .regular) - if myMusicType == .like { + if type == .like { newLabel.text = likeCountLabel.text } else { newLabel.text = dropCountLabel.text @@ -483,7 +481,6 @@ private extension MyPageViewController { .bind(with: self) { owner, _ in owner.listTypeTapEvent.accept(.drop) owner.updateTapListUI(by: .drop) - owner.myMusicType = .drop } .disposed(by: disposeBag) @@ -491,7 +488,6 @@ private extension MyPageViewController { .bind(with: self) { owner, _ in owner.listTypeTapEvent.accept(.like) owner.updateTapListUI(by: .like) - owner.myMusicType = .like } .disposed(by: disposeBag) } @@ -538,16 +534,25 @@ private extension MyPageViewController { owner.selectedMusicEvent.accept(item.id) } .disposed(by: disposeBag) + + typealias ScrollViewState = (contentOffset: CGPoint, type: MyMusicType) + + scrollView.rx.contentOffset + .withLatestFrom(listTypeTapEvent) { (contentOffset: $0, type: $1) } + .bind(with: self) { owner, state in + owner.handleScrollEvent(contentOffset: state.contentOffset, type: state.type) + } + .disposed(by: disposeBag) } // MARK: - Data Binding private func bindViewModel() { let input = MyPageViewModel.Input( - viewWillAppearEvent: viewWillAppearEvent, - listTypeTapEvent: listTypeTapEvent, - levelPolicyTapEvent: levelPolicyTapEvent, - selectedMusicEvent: selectedMusicEvent + viewWillAppearEvent: viewWillAppearEvent.asObservable(), + listTypeTapEvent: listTypeTapEvent.asObservable(), + levelPolicyTapEvent: levelPolicyTapEvent.asObservable(), + selectedMusicEvent: selectedMusicEvent.asObservable() ) let output = viewModel.convert(input: input, disposedBag: disposeBag) @@ -648,22 +653,20 @@ private extension MyPageViewController { // MARK: - ScrollView Delegate -extension MyPageViewController: UIScrollViewDelegate { - func scrollViewDidScroll(_ scrollView: UIScrollView) { +extension MyPageViewController { + func handleScrollEvent(contentOffset: CGPoint, type: MyMusicType) { // 맨 위로 스크롤하기 버튼 활성화 - if scrollView == self.scrollView { - let offsetY = scrollView.contentOffset.y - if offsetY > 400 { - scrollToTopButton.isHidden = false - } else { - scrollToTopButton.isHidden = true - } + let offsetY = contentOffset.y + if offsetY > 400 { + scrollToTopButton.isHidden = false + } else { + scrollToTopButton.isHidden = true } // 드랍, 좋아요 탭 상단에 고정시키기 - if scrollView.contentOffset.y > 343 { + if contentOffset.y > 343 { if self.stickyTapListStackView == nil { - self.stickyTapListStackView = createTapListStackView() + self.stickyTapListStackView = createTapListStackView(with: type) self.stickyTopDimmedView = createDimmedView(isFromTop: true) guard let stickyTapListStackView = stickyTapListStackView else { return } diff --git a/StreetDrop/StreetDrop/Presentation/MyPage/ViewModel/MyPageViewModel.swift b/StreetDrop/StreetDrop/Presentation/MyPage/ViewModel/MyPageViewModel.swift index 2cdec98..cce1bf5 100644 --- a/StreetDrop/StreetDrop/Presentation/MyPage/ViewModel/MyPageViewModel.swift +++ b/StreetDrop/StreetDrop/Presentation/MyPage/ViewModel/MyPageViewModel.swift @@ -24,10 +24,10 @@ final class MyPageViewModel { extension MyPageViewModel: ViewModel { struct Input { - let viewWillAppearEvent: PublishRelay - let listTypeTapEvent: PublishRelay - let levelPolicyTapEvent: PublishRelay - let selectedMusicEvent: PublishRelay + let viewWillAppearEvent: Observable + let listTypeTapEvent: Observable + let levelPolicyTapEvent: Observable + let selectedMusicEvent: Observable } struct Output { @@ -51,23 +51,28 @@ extension MyPageViewModel: ViewModel { func convert(input: Input, disposedBag: RxSwift.DisposeBag) -> Output { let output = Output() + let lastestListType = BehaviorRelay(value: .drop) input.viewWillAppearEvent .bind(with: self) { owner, _ in owner.fetchLevelItems(output: output, disposedBag: disposedBag) owner.fetchLevelProgress(output: output, disposeBag: disposedBag) - owner.fetchMyDropMusicsSections(output: output, disposedBag: disposedBag) - owner.fetchMyLikeMusicsSections(output: output, disposedBag: disposedBag) + + lastestListType.accept(lastestListType.value) } .disposed(by: disposedBag) input.listTypeTapEvent + .bind(to: lastestListType) + .disposed(by: disposedBag) + + lastestListType .bind(with: self) { owner, type in switch type { case .drop: - output.myMusicsSections.accept(owner.myDropMusicSections) + owner.fetchMyDropMusicsSections(output: output, disposedBag: disposedBag) case .like: - output.myMusicsSections.accept(owner.myLikeMusicSections) + owner.fetchMyLikeMusicsSections(output: output, disposedBag: disposedBag) } } .disposed(by: disposedBag) @@ -141,8 +146,8 @@ private extension MyPageViewModel { model.fetchMyDropList() .subscribe(with: self, onSuccess: { owner, totalMusics in output.totalDropMusicsCount.accept(totalMusics.totalCount) - owner.myDropMusicSections = owner.convertToSectionTypes(from: totalMusics) - output.myMusicsSections.accept(owner.myDropMusicSections) + let myMusicsSections = owner.convertToSectionTypes(from: totalMusics) + output.myMusicsSections.accept(myMusicsSections) }, onFailure: { _, error in print("❌Fetching My Drop List Error: \(error.localizedDescription)") }) @@ -153,7 +158,8 @@ private extension MyPageViewModel { model.fetchMyLikeList() .subscribe(with: self, onSuccess: { owner, totalMusics in output.totalLikeMusicsCount.accept(totalMusics.totalCount) - owner.myLikeMusicSections = owner.convertToSectionTypes(from: totalMusics) + let myMusicsSections = owner.convertToSectionTypes(from: totalMusics) + output.myMusicsSections.accept(myMusicsSections) }, onFailure: { _, error in print("❌Fetching My Like List Error: \(error.localizedDescription)") })