From f81ce1f6aca6d8c9c1ba806888cec4e50014ca15 Mon Sep 17 00:00:00 2001 From: kimscastle Date: Thu, 23 Nov 2023 13:48:15 +0900 Subject: [PATCH] =?UTF-8?q?[REFACTOR]=20Cell=20reuse=EC=8B=9C=20Combine?= =?UTF-8?q?=EC=9D=98=20stream=EC=97=B0=EA=B2=B0=EB=AC=B8=EC=A0=9C=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0(#179)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Cells/CurriculumTableViewCell.swift | 49 ++----- .../CurriculumViewController.swift | 130 ++---------------- .../ViewModel/CurriculumViewViewModel.swift | 7 +- .../CurriculumViewViewModelImpl.swift | 22 +-- 4 files changed, 33 insertions(+), 175 deletions(-) diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/Cells/CurriculumTableViewCell.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/Cells/CurriculumTableViewCell.swift index 8c7dd686..5bd5bb49 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/Cells/CurriculumTableViewCell.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/Cells/CurriculumTableViewCell.swift @@ -11,21 +11,10 @@ import Combine import SnapKit -//protocol CurriculumTableViewToggleButtonTappedProtocol: AnyObject { -// func toggleButtonTapped(indexPath: IndexPath?) -// func moveToListByWeekButtonTapped(indexPath: IndexPath?) -//} - final class CurriculumTableViewCell: UITableViewCell, TableViewCellRegisterDequeueProtocol { - var toggleButtonTapped = PassthroughSubject() var rightArrowButtonTapped = PassthroughSubject() - var cancelBag = Set() - -// weak var delegate: CurriculumTableViewToggleButtonTappedProtocol? - - var cellIndexPath: IndexPath? private let curriculumWeekLabelView = UIView() private let curriculumWholeStackView = LHStackView(axis: .vertical, spacing: 15) @@ -35,9 +24,7 @@ final class CurriculumTableViewCell: UITableViewCell, TableViewCellRegisterDeque private let contentTextLabel = LHLabel(type: .body3R, color: .gray500, lines: 0) private let contentImageView = LHImageView(contentMode: .scaleToFill) private let divider = LHUnderLine(lineColor: .gray800) - lazy var curriculumToggleDirectionButton = LHToggleImageButton(normal: ImageLiterals.Curriculum.arrowDownSmall, - select: ImageLiterals.Curriculum.arrowUpSmall) - private lazy var moveToArticleListByWeekButton = LHImageButton(setImage: ImageLiterals.Curriculum.arrowRightCircle) + private var moveToArticleListByWeekButton = LHImageButton(setImage: ImageLiterals.Curriculum.arrowRightCircle) var inputData: CurriculumDummyData? { didSet { @@ -58,6 +45,11 @@ final class CurriculumTableViewCell: UITableViewCell, TableViewCellRegisterDeque required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } + + override func prepareForReuse() { + super.prepareForReuse() + cancelBag.removeAll() + } } private extension CurriculumTableViewCell { @@ -70,13 +62,10 @@ private extension CurriculumTableViewCell { self.backgroundColor = .designSystem(.background) weekTitleLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal) contentImageView.isUserInteractionEnabled = true - curriculumToggleDirectionButton.marginImageWithText(margin: 19) - curriculumToggleDirectionButton.setContentCompressionResistancePriority(.required, for: .horizontal) - } func setHierarchy() { - curriculumWeekLabelView.addSubviews(weekLabel, weekTitleLabel, curriculumToggleDirectionButton) + curriculumWeekLabelView.addSubviews(weekLabel, weekTitleLabel) contentImageView.addSubviews(moveToArticleListByWeekButton) curriculumContentStackView.addArrangedSubviews(contentImageView, contentTextLabel) curriculumWholeStackView.addArrangedSubviews(curriculumWeekLabelView, curriculumContentStackView) @@ -95,12 +84,7 @@ private extension CurriculumTableViewCell { $0.centerY.equalTo(weekLabel) $0.leading.equalTo(weekLabel.snp.trailing).offset(8).priority(.high) } - - curriculumToggleDirectionButton.snp.makeConstraints { - $0.leading.greaterThanOrEqualTo(weekTitleLabel.snp.trailing).offset(8) - $0.centerY.equalTo(weekLabel) - $0.trailing.equalToSuperview().offset(12) - } + curriculumWholeStackView.snp.makeConstraints { $0.top.bottom.equalToSuperview().inset(16) @@ -124,17 +108,9 @@ private extension CurriculumTableViewCell { } func bindInput() { - curriculumToggleDirectionButton.tapPublisher - .sink { _ in - self.toggleButtonTapped.send(()) - } - .store(in: &cancelBag) - - moveToArticleListByWeekButton.tapPublisher - .sink { _ in - self.rightArrowButtonTapped.send(()) - } - .store(in: &cancelBag) + moveToArticleListByWeekButton.addButtonAction { sender in + self.rightArrowButtonTapped.send(()) + } } func configureData(_ inputData: CurriculumDummyData) { @@ -143,9 +119,6 @@ private extension CurriculumTableViewCell { self.contentImageView.image = inputData.curriculumImage self.contentTextLabel.text = inputData.curriculumText self.contentTextLabel.setTextWithLineHeight(lineHeight: 22) - self.curriculumContentStackView.isHidden = !inputData.isExpanded self.weekLabel.textColor = inputData.isExpanded ? .designSystem(.componentLionRed) : .designSystem(.gray500) } } - - diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewControllers/CurriculumViewController.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewControllers/CurriculumViewController.swift index 3a618d83..a8c58247 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewControllers/CurriculumViewController.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewControllers/CurriculumViewController.swift @@ -16,14 +16,10 @@ protocol CurriculumControllerable where Self: UIViewController {} final class CurriculumViewController: UIViewController, CurriculumControllerable { -// var navigator: CurriculumNavigation -// private let manager: CurriculumManager - private let viewDidLayoutSubviewSubject = PassthroughSubject() private let viewWillAppearSubject = PassthroughSubject() private let bookmarkButtonTapped = PassthroughSubject() private let myPageButtonTapped = PassthroughSubject() - private let rightArrowButtonTapped = PassthroughSubject() - private let toggleButtonTapped = PassthroughSubject() + private let rightArrowButtonTapped = PassthroughSubject() private var cancelBag = Set() @@ -38,14 +34,7 @@ final class CurriculumViewController: UIViewController, CurriculumControllerable private let curriculumTableView = CurriculumTableView() private let viewModel: any CurriculumViewViewModel - private var isFirstPresented: Bool = true -// private var curriculumViewDatas = CurriculumMonthData.dummy() -// private var userInfoData: UserInfoData? { -// didSet { -// configureUserInfoData() -// } -// } - + init(viewModel: some CurriculumViewViewModel) { self.viewModel = viewModel super.init(nibName: nil, bundle: nil) @@ -58,6 +47,7 @@ final class CurriculumViewController: UIViewController, CurriculumControllerable public override func viewDidLoad() { super.viewDidLoad() setUI() + setNavigation() setHierarchy() setLayout() setDelegate() @@ -66,16 +56,8 @@ final class CurriculumViewController: UIViewController, CurriculumControllerable bind() } - override func viewDidLayoutSubviews() { -// self.viewDidLayoutSubviewSubject.send(()) -// if isFirstPresented { -// self.scrollToUserWeek() -// } - } - override func viewWillAppear(_ animated: Bool) { showLoading() -// getCurriculumData() self.viewWillAppearSubject.send(()) } @@ -96,12 +78,10 @@ final class CurriculumViewController: UIViewController, CurriculumControllerable } private func bind() { - let input = CurriculumViewViewModelInput(viewDidLayoutSubviews: viewDidLayoutSubviewSubject, - viewWillAppear: viewWillAppearSubject, + let input = CurriculumViewViewModelInput(viewWillAppear: viewWillAppearSubject, bookmarkButtonTapped: bookmarkButtonTapped, myPageButtonTapped: myPageButtonTapped, - rightArrowButtonTapped: rightArrowButtonTapped, - toggleButtonTapped: toggleButtonTapped) + rightArrowButtonTapped: rightArrowButtonTapped) let output = viewModel.transform(input: input) output.curriculumMonth .receive(on: RunLoop.main) @@ -111,53 +91,30 @@ final class CurriculumViewController: UIViewController, CurriculumControllerable self?.hideLoading() } .store(in: &cancelBag) - - output.toggleButtonTapped - .receive(on: RunLoop.main) - .sink { [weak self] datas in - self?.applySnapshot(monthData: datas) - } - .store(in: &cancelBag) - -// output.firstScrollIndexPath -// .sink { [weak self] indexPath in -// self?.scrollToUserWeek(indexPath: indexPath) -// } -// .store(in: &cancelBag) } private func setDataSource() { self.datasource = UITableViewDiffableDataSource(tableView: self.curriculumTableView, cellProvider: { tableView, indexPath, itemIdentifier in let cell = CurriculumTableViewCell.dequeueReusableCell(to: tableView) - cell.toggleButtonTapped - .sink { [weak self] _ in - self?.toggleButtonTapped.send(indexPath) - } - .store(in: &self.cancelBag) - cell.rightArrowButtonTapped .sink { [weak self] _ in - print(indexPath.section, indexPath.row) + self?.rightArrowButtonTapped.send(indexPath) } .store(in: &cell.cancelBag) - cell.inputData = itemIdentifier cell.selectionStyle = .none - cell.curriculumToggleDirectionButton.isSelected = itemIdentifier.isExpanded return cell }) } private func applySnapshot(monthData: [CurriculumMonthData]) { var snapshot = NSDiffableDataSourceSnapshot() - monthData.forEach { month in snapshot.appendSections([month]) snapshot.appendItems(month.weekDatas, toSection: month) } self.datasource.defaultRowAnimation = .middle self.datasource.apply(snapshot) - } } @@ -171,13 +128,16 @@ private extension CurriculumViewController { view.backgroundColor = .designSystem(.background) } + func setNavigation() { + self.navigationController?.isNavigationBarHidden = true + } + func setHierarchy() { dDayView.addSubview(dDayLabel) view.addSubviews(navigationBar, progressBar, curriculumUserInfoView, curriculumTableView, gradientImage, dDayView) } func setLayout() { - self.navigationController?.isNavigationBarHidden = true navigationBar.snp.makeConstraints{ $0.top.equalTo(self.view.safeAreaLayoutGuide.snp.top) $0.leading.trailing.equalToSuperview() @@ -222,11 +182,6 @@ private extension CurriculumViewController { curriculumTableView.delegate = self } - func scrollToUserWeek(indexPath: IndexPath) { - self.curriculumTableView.scrollToRow(at: indexPath, at: .top, animated: false) - - } - func configureUserInfoData(userInfoData: UserInfoData?) { guard let userInfoData else { return } dDayLabel.text = "D-\(userInfoData.remainingDay)" @@ -240,73 +195,8 @@ private extension CurriculumViewController { extension CurriculumViewController: UITableViewDelegate { func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { let sectionModel = datasource.snapshot().sectionIdentifiers[section] - let headerView = CurriculumTableViewHeaderView() headerView.configureHeaderView(month: sectionModel.month) return headerView } - -} - -// func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { -// return curriculumViewDatas[section].weekDatas.count -// } -// -// func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { -// let cell = CurriculumTableViewCell.dequeueReusableCell(to: tableView) -// let data = curriculumViewDatas[indexPath.section].weekDatas[indexPath.row] -// cell.inputData = data -// cell.selectionStyle = .none -//// cell.delegate = self -// cell.cellIndexPath = indexPath -// cell.curriculumToggleDirectionButton.isSelected = data.isExpanded -// return cell -// } -// -// func numberOfSections(in tableView: UITableView) -> Int { -// return curriculumViewDatas.count -// } -//} - -extension CurriculumViewController { -// func toggleButtonTapped(indexPath: IndexPath?) { -// self.isFirstPresented = false -// guard let indexPath else { return } -// let previousWeekDatas = curriculumViewDatas[indexPath.section].weekDatas[indexPath.row] -// curriculumViewDatas[indexPath.section].weekDatas[indexPath.row].isExpanded = !previousWeekDatas.isExpanded -// curriculumTableView.reloadRows(at: [indexPath], with: .automatic) -// } -// -// func moveToListByWeekButtonTapped(indexPath: IndexPath?) { -// guard let indexPath else { return } -// let itemIndex = indexPath.section * 4 + indexPath.row + 4 -// self.navigator.articleListCellTapped(itemIndex: itemIndex) -// } } - -//extension CurriculumViewController: ViewControllerServiceable { -// func handleError(_ error: NetworkError) { -// switch error { -// case .unAuthorizedError: -// self.navigator.checkTokenIsExpired() -// case .clientError(_, let message): -// LHToast.show(message: "\(message)") -// default: -// LHToast.show(message: error.description) -// } -// } -//} - -//extension CurriculumViewController { -// func getCurriculumData() { -// Task { -// do { -// userInfoData = try await manager.getCurriculumServiceInfo() -// hideLoading() -// } catch { -// guard let error = error as? NetworkError else { return } -// handleError(error) -// } -// } -// } -//} diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewModel/CurriculumViewViewModel.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewModel/CurriculumViewViewModel.swift index 66d8428c..82adc5ab 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewModel/CurriculumViewViewModel.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewModel/CurriculumViewViewModel.swift @@ -13,17 +13,12 @@ protocol CurriculumViewViewModelPresentable {} protocol CurriculumViewViewModel: ViewModel where Input == CurriculumViewViewModelInput, Output == CurriculumViewViewModelOutput {} struct CurriculumViewViewModelInput { - let viewDidLayoutSubviews: PassthroughSubject let viewWillAppear: PassthroughSubject let bookmarkButtonTapped: PassthroughSubject let myPageButtonTapped: PassthroughSubject - let rightArrowButtonTapped: PassthroughSubject - let toggleButtonTapped: PassthroughSubject + let rightArrowButtonTapped: PassthroughSubject } struct CurriculumViewViewModelOutput { - let firstScrollIndexPath: AnyPublisher let curriculumMonth: AnyPublisher<(userInfo: UserInfoData, monthData: [CurriculumMonthData]), Never> - let toggleButtonTapped: AnyPublisher<[CurriculumMonthData], Never> -// let userInfo: AnyPublisher } diff --git a/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewModel/CurriculumViewViewModelImpl.swift b/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewModel/CurriculumViewViewModelImpl.swift index adecf5dc..1c12c386 100644 --- a/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewModel/CurriculumViewViewModelImpl.swift +++ b/LionHeart-iOS/LionHeart-iOS/Scenes/Curriculum/ViewModel/CurriculumViewViewModelImpl.swift @@ -76,18 +76,19 @@ final class CurriculumViewViewModelImpl: CurriculumViewViewModel, CurriculumView input.rightArrowButtonTapped .sink { [weak self] index in - self?.navigationSubject.send(.rightArrowButton(index: index)) + let itemIndex = index.section * 4 + index.row + 4 + self?.navigationSubject.send(.rightArrowButton(index: itemIndex)) } .store(in: &cancelBag) - let toggleButtonTapped = input.toggleButtonTapped - .map { [weak self] indexPath -> [CurriculumMonthData] in - guard let self = self else { return [] } - let previousWeekDatas = self.curriculumViewDatas[indexPath.section].weekDatas[indexPath.row] - self.curriculumViewDatas[indexPath.section].weekDatas[indexPath.row].isExpanded = !previousWeekDatas.isExpanded - return self.curriculumViewDatas - } - .eraseToAnyPublisher() +// let toggleButtonTapped = input.toggleButtonTapped +// .map { [weak self] indexPath -> [CurriculumMonthData] in +// guard let self = self else { return [] } +// let previousWeekDatas = self.curriculumViewDatas[indexPath.section].weekDatas[indexPath.row] +// self.curriculumViewDatas[indexPath.section].weekDatas[indexPath.row].isExpanded = !previousWeekDatas.isExpanded +// return self.curriculumViewDatas +// } +// .eraseToAnyPublisher() @@ -141,8 +142,7 @@ final class CurriculumViewViewModelImpl: CurriculumViewViewModel, CurriculumView - return Output(firstScrollIndexPath: scrollIndexPath, - curriculumMonth: curriculumMonth, toggleButtonTapped: toggleButtonTapped) + return Output(curriculumMonth: curriculumMonth) } }