Skip to content

Commit

Permalink
[REFACTOR] Cell reuse시 Combine의 stream연결문제 해결(#179)
Browse files Browse the repository at this point in the history
  • Loading branch information
kimscastle committed Nov 23, 2023
1 parent 7eb9bee commit f81ce1f
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 175 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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<Void, Never>()
var rightArrowButtonTapped = PassthroughSubject<Void, Never>()

var cancelBag = Set<AnyCancellable>()

// weak var delegate: CurriculumTableViewToggleButtonTappedProtocol?

var cellIndexPath: IndexPath?

private let curriculumWeekLabelView = UIView()
private let curriculumWholeStackView = LHStackView(axis: .vertical, spacing: 15)
Expand All @@ -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 {
Expand All @@ -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 {
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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) {
Expand All @@ -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)
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -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<Void, Never>()
private let viewWillAppearSubject = PassthroughSubject<Void, Never>()
private let bookmarkButtonTapped = PassthroughSubject<Void, Never>()
private let myPageButtonTapped = PassthroughSubject<Void, Never>()
private let rightArrowButtonTapped = PassthroughSubject<Int, Never>()
private let toggleButtonTapped = PassthroughSubject<IndexPath, Never>()
private let rightArrowButtonTapped = PassthroughSubject<IndexPath, Never>()

private var cancelBag = Set<AnyCancellable>()

Expand All @@ -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)
Expand All @@ -58,6 +47,7 @@ final class CurriculumViewController: UIViewController, CurriculumControllerable
public override func viewDidLoad() {
super.viewDidLoad()
setUI()
setNavigation()
setHierarchy()
setLayout()
setDelegate()
Expand All @@ -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(())
}

Expand All @@ -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)
Expand All @@ -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<CurriculumMonthData, CurriculumDummyData>()

monthData.forEach { month in
snapshot.appendSections([month])
snapshot.appendItems(month.weekDatas, toSection: month)
}
self.datasource.defaultRowAnimation = .middle
self.datasource.apply(snapshot)

}
}

Expand All @@ -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()
Expand Down Expand Up @@ -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)"
Expand All @@ -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)
// }
// }
// }
//}
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,12 @@ protocol CurriculumViewViewModelPresentable {}
protocol CurriculumViewViewModel: ViewModel where Input == CurriculumViewViewModelInput, Output == CurriculumViewViewModelOutput {}

struct CurriculumViewViewModelInput {
let viewDidLayoutSubviews: PassthroughSubject<Void, Never>
let viewWillAppear: PassthroughSubject<Void, Never>
let bookmarkButtonTapped: PassthroughSubject<Void, Never>
let myPageButtonTapped: PassthroughSubject<Void, Never>
let rightArrowButtonTapped: PassthroughSubject<Int, Never>
let toggleButtonTapped: PassthroughSubject<IndexPath, Never>
let rightArrowButtonTapped: PassthroughSubject<IndexPath, Never>
}

struct CurriculumViewViewModelOutput {
let firstScrollIndexPath: AnyPublisher<IndexPath, Never>
let curriculumMonth: AnyPublisher<(userInfo: UserInfoData, monthData: [CurriculumMonthData]), Never>
let toggleButtonTapped: AnyPublisher<[CurriculumMonthData], Never>
// let userInfo: AnyPublisher<UserInfoData, Never>
}
Original file line number Diff line number Diff line change
Expand Up @@ -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()



Expand Down Expand Up @@ -141,8 +142,7 @@ final class CurriculumViewViewModelImpl: CurriculumViewViewModel, CurriculumView



return Output(firstScrollIndexPath: scrollIndexPath,
curriculumMonth: curriculumMonth, toggleButtonTapped: toggleButtonTapped)
return Output(curriculumMonth: curriculumMonth)
}

}
Expand Down

0 comments on commit f81ce1f

Please sign in to comment.