diff --git a/Runnect-iOS/Runnect-iOS/Global/Literal/ImageLiterals.swift b/Runnect-iOS/Runnect-iOS/Global/Literal/ImageLiterals.swift index 20cc7de1..f0823805 100644 --- a/Runnect-iOS/Runnect-iOS/Global/Literal/ImageLiterals.swift +++ b/Runnect-iOS/Runnect-iOS/Global/Literal/ImageLiterals.swift @@ -44,7 +44,9 @@ enum ImageLiterals { static var icLogoCircle: UIImage { .load(named: "ic_logo_circle") } static var icMore: UIImage { .load(named: "ic_more") } static var icPlus: UIImage { .load(named: "ic_plus") } - + static var icCheck: UIImage { .load(named: "ic_check") } + static var icCheckFill: UIImage { .load(named: "ic_check_fill") } + // img static var imgBackground: UIImage { .load(named: "img_background") } static var imgLogo: UIImage { .load(named: "img_logo") } diff --git a/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_check.imageset/Contents.json b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_check.imageset/Contents.json new file mode 100644 index 00000000..112b03c2 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_check.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "Group 9499.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Group 9499@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Group 9499@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_check.imageset/Group 9499.png b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_check.imageset/Group 9499.png new file mode 100644 index 00000000..8bf3ea8f Binary files /dev/null and b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_check.imageset/Group 9499.png differ diff --git a/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_check.imageset/Group 9499@2x.png b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_check.imageset/Group 9499@2x.png new file mode 100644 index 00000000..7c50cd84 Binary files /dev/null and b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_check.imageset/Group 9499@2x.png differ diff --git a/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_check.imageset/Group 9499@3x.png b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_check.imageset/Group 9499@3x.png new file mode 100644 index 00000000..170a6a4d Binary files /dev/null and b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_check.imageset/Group 9499@3x.png differ diff --git a/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_check_fill.imageset/Contents.json b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_check_fill.imageset/Contents.json new file mode 100644 index 00000000..34531054 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_check_fill.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "Group 9515.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Group 9515@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Group 9515@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_check_fill.imageset/Group 9515.png b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_check_fill.imageset/Group 9515.png new file mode 100644 index 00000000..a21fffbe Binary files /dev/null and b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_check_fill.imageset/Group 9515.png differ diff --git a/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_check_fill.imageset/Group 9515@2x.png b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_check_fill.imageset/Group 9515@2x.png new file mode 100644 index 00000000..2c1cbdc5 Binary files /dev/null and b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_check_fill.imageset/Group 9515@2x.png differ diff --git a/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_check_fill.imageset/Group 9515@3x.png b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_check_fill.imageset/Group 9515@3x.png new file mode 100644 index 00000000..e2c3ae3d Binary files /dev/null and b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_check_fill.imageset/Group 9515@3x.png differ diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseStorage/VC/CourseStorageVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseStorage/VC/CourseStorageVC.swift index d7d44348..6aa3809d 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/CourseStorage/VC/CourseStorageVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseStorage/VC/CourseStorageVC.swift @@ -86,7 +86,6 @@ extension CourseStorageVC { private func bindUI() { viewPager.$selectedTabIndex.sink { [weak self] selectedTabIndex in guard let self = self else { return } - print(selectedTabIndex) self.deleteCourseButton.isHidden = (selectedTabIndex != 0) }.store(in: cancelBag) diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseStorage/Views/CVC/CourseListCVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseStorage/Views/CVC/CourseListCVC.swift index 7ca1f921..4dbca07b 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/CourseStorage/Views/CVC/CourseListCVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseStorage/Views/CVC/CourseListCVC.swift @@ -76,6 +76,13 @@ final class CourseListCVC: UICollectionViewCell { $0.backgroundColor = .w1 } + private let selectIndicatorButton = UIButton(type: .custom).then { + $0.setImage(ImageLiterals.icCheckFill, for: .selected) + $0.setImage(ImageLiterals.icCheck, for: .normal) + $0.isSelected = false + $0.isHidden = true + } + // MARK: - initialization override init(frame: CGRect) { @@ -83,6 +90,7 @@ final class CourseListCVC: UICollectionViewCell { self.setUI() self.setLayout() self.setAddTarget() + } required init?(coder: NSCoder) { @@ -97,18 +105,17 @@ extension CourseListCVC { likeButton.addTarget(self, action: #selector(likeButtonDidTap), for: .touchUpInside) } - func setData(imageURL: String, title: String, location: String?, didLike: Bool?, indexPath: Int? = nil) { + func setData(imageURL: String, title: String, location: String?, didLike: Bool?, indexPath: Int? = nil, isEditMode: Bool = false) { self.courseImageView.setImage(with: imageURL) self.titleLabel.text = title self.indexPath = indexPath - if let location = location { self.locationLabel.text = location } - if let didLike = didLike { self.likeButton.isSelected = didLike } + self.selectIndicatorButton.isHidden = !isEditMode } func selectCell(didSelect: Bool) { @@ -116,9 +123,12 @@ extension CourseListCVC { courseImageView.layer.borderColor = UIColor.m1.cgColor courseImageView.layer.borderWidth = 2 imageCoverView.isHidden = false + selectIndicatorButton.isSelected = true } else { courseImageView.layer.borderColor = UIColor.clear.cgColor imageCoverView.isHidden = true + selectIndicatorButton.isSelected = false + } } } @@ -143,7 +153,7 @@ extension CourseListCVC { } private func setLayout() { - self.contentView.addSubviews(courseImageView, imageCoverView, labelStackView, likeButton) + self.contentView.addSubviews(courseImageView, imageCoverView, labelStackView, likeButton, selectIndicatorButton) courseImageView.snp.makeConstraints { make in make.leading.top.trailing.equalToSuperview() @@ -162,6 +172,13 @@ extension CourseListCVC { make.height.equalTo(20) } + selectIndicatorButton.snp.makeConstraints { make in + make.top.leading.equalToSuperview().inset(8) + make.leading.equalToSuperview().offset(8) + make.width.equalTo(20) + make.height.equalTo(20) + } + labelStackView.snp.makeConstraints { make in make.top.equalTo(courseImageView.snp.bottom).offset(4) make.leading.equalToSuperview() diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseStorage/Views/CourseListView/PrivateCourseListView.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseStorage/Views/CourseListView/PrivateCourseListView.swift index 08256ebd..7106bb88 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/CourseStorage/Views/CourseListView/PrivateCourseListView.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseStorage/Views/CourseListView/PrivateCourseListView.swift @@ -32,7 +32,7 @@ final class PrivateCourseListView: UIView { isEditMode ? startEditMode() : finishEditMode() } } - + final let collectionViewInset = UIEdgeInsets(top: 28, left: 16, bottom: 28, right: 16) final let itemSpacing: CGFloat = 10 final let lineSpacing: CGFloat = 20 @@ -119,8 +119,8 @@ extension PrivateCourseListView { extension PrivateCourseListView { @objc func editButtonDidTap() { isEditMode.toggle() - self.delegate?.courseListEditButtonTapped() + self.courseListCollectionView.reloadData() } private func startEditMode() { @@ -203,7 +203,7 @@ extension PrivateCourseListView: UICollectionViewDelegate, UICollectionViewDataS let model = courseList[indexPath.item] let cellTitle = "\(model.departure.region) \(model.departure.city)" - cell.setData(imageURL: model.image, title: cellTitle, location: nil, didLike: nil) + cell.setData(imageURL: model.image, title: cellTitle, location: nil, didLike: nil, isEditMode: isEditMode) return cell } @@ -219,16 +219,11 @@ extension PrivateCourseListView: UICollectionViewDelegate, UICollectionViewDataS } func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) { - guard let selectedCells = collectionView.indexPathsForSelectedItems else { - return - } - guard let cell = collectionView.cellForItem(at: indexPath) as? CourseListCVC else { return } if isEditMode { cell.selectCell(didSelect: false) } - delegate?.selectCellDidTapped() } } diff --git a/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/UploadedCourseInfoVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/UploadedCourseInfoVC.swift index b713da69..4a990933 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/UploadedCourseInfoVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/UploadedCourseInfoVC.swift @@ -19,7 +19,11 @@ final class UploadedCourseInfoVC: UIViewController { private var uploadedCourseList = [PublicCourse]() - var isEditMode: Bool = false + var isEditMode: Bool = false { + didSet { + isEditMode ? startEditMode() : finishEditMode() + } + } private var deleteToCourseId = [Int]() @@ -104,7 +108,7 @@ final class UploadedCourseInfoVC: UIViewController { extension UploadedCourseInfoVC { private func setData(courseList: [PublicCourse]) { self.uploadedCourseList = courseList - UploadedCourseInfoCollectionView.reloadData() + self.UploadedCourseInfoCollectionView.reloadData() self.emptyView.isHidden = !courseList.isEmpty self.deleteCourseButton.isHidden = true self.beforeEditTopView.isHidden = courseList.isEmpty @@ -127,10 +131,30 @@ extension UploadedCourseInfoVC { self.editButton.addTarget(self, action: #selector(editButtonDidTap), for: .touchUpInside) } + private func startEditMode() { + self.totalNumOfRecordlabel.text = "코스 선택" + self.editButton.setTitle("취소", for: .normal) + self.deleteCourseButton.isHidden = false + } + + private func finishEditMode() { + self.totalNumOfRecordlabel.text = "총 코스 \(self.uploadedCourseList.count)개" + self.editButton.setTitle("편집", for: .normal) + self.deleteCourseButton.isEnabled = false + self.deleteCourseButton.setTitle(title: "삭제하기") + self.deleteCourseButton.isHidden = true + self.deselectAllItems() + } + + private func deselectAllItems() { + guard let selectedItems = UploadedCourseInfoCollectionView.indexPathsForSelectedItems else { return } + for indexPath in selectedItems { UploadedCourseInfoCollectionView.deselectItem(at: indexPath, animated: false) } + } private func setDeleteButton() { deleteCourseButton.addTarget(self, action: #selector(deleteCourseButtonDidTap), for: .touchUpInside) } + } // MARK: - @objc Function @@ -155,22 +179,8 @@ extension UploadedCourseInfoVC { } @objc func editButtonDidTap() { - if isEditMode { - self.totalNumOfRecordlabel.text = "총 코스 \(self.uploadedCourseList.count)개" - self.editButton.setTitle("편집", for: .normal) - self.deleteCourseButton.isEnabled = false - self.deleteCourseButton.setTitle(title: "삭제하기") - self.courseListCollectionView.reloadData() - isEditMode = false - self.deleteCourseButton.isHidden = true - } else { - self.totalNumOfRecordlabel.text = "기록 선택" - self.editButton.setTitle("취소", for: .normal) - - self.deleteCourseButton.isHidden = false - self.courseListCollectionView.reloadData() - isEditMode = true - } + isEditMode.toggle() + self.UploadedCourseInfoCollectionView.reloadData() } } @@ -257,7 +267,7 @@ extension UploadedCourseInfoVC: UICollectionViewDelegateFlowLayout { // MARK: - UICollectionViewDataSource -extension UploadedCourseInfoVC: UICollectionViewDataSource { +extension UploadedCourseInfoVC: UICollectionViewDelegate, UICollectionViewDataSource { func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return uploadedCourseList.count } @@ -266,65 +276,53 @@ extension UploadedCourseInfoVC: UICollectionViewDataSource { guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CourseListCVC.className, for: indexPath) as? CourseListCVC else { return UICollectionViewCell() } cell.setCellType(type: .title) - let model = uploadedCourseList[indexPath.item] - let cellTitle = "\(model.departure.region) \(model.departure.city)" - cell.setData(imageURL: model.image, title: cellTitle, location: nil, didLike: nil) - - if isEditMode { - // selectCell 표시 - if let selectedCells = collectionView.indexPathsForSelectedItems, selectedCells.contains(indexPath) { - cell.selectCell(didSelect: false) - } else { cell.selectCell(didSelect: true) - } + if let selectedCells = collectionView.indexPathsForSelectedItems, selectedCells.contains(indexPath) { + cell.selectCell(didSelect: true) } else { - cell.setCellType(type: .title) - guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CourseListCVC.className, - for: indexPath) - as? CourseListCVC else { return UICollectionViewCell() } - cell.setCellType(type: .title) + cell.selectCell(didSelect: false) } + + let model = uploadedCourseList[indexPath.item] + let cellTitle = "\(model.departure.region) \(model.departure.city)" + cell.setData(imageURL: model.image, title: cellTitle, location: nil, didLike: nil, isEditMode: isEditMode) return cell } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { - guard collectionView.cellForItem(at: indexPath) is CourseListCVC else { return } - guard let selectedCells = collectionView.indexPathsForSelectedItems else { return } guard let cell = collectionView.cellForItem(at: indexPath) as? CourseListCVC else { return } let publicCourseModel = uploadedCourseList[indexPath.item] if isEditMode { self.deleteCourseButton.isEnabled = true - let countSelectCells = selectedCells.count - self.deleteCourseButton.setTitle(title: "삭제하기(\(countSelectCells))") cell.selectCell(didSelect: true) + guard let selectedCells = collectionView.indexPathsForSelectedItems else { return } + + let countSelectCells = selectedCells.count + + if isEditMode { + self.deleteCourseButton.setTitle(title: "삭제하기(\(countSelectCells))") + } + self.deleteCourseButton.setEnabled(countSelectCells != 0) } else { collectionView.deselectItem(at: indexPath, animated: true) - self.deleteCourseButton.setTitle(title: "삭제하기") - self.deleteCourseButton.setEnabled(true) let courseDetailVC = CourseDetailVC() courseDetailVC.setCourseId(courseId: publicCourseModel.courseId, publicCourseId: publicCourseModel.id) courseDetailVC.hidesBottomBarWhenPushed = true self.navigationController?.pushViewController(courseDetailVC, animated: true) - cell.selectCell(didSelect: false) } } func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) { - guard collectionView.cellForItem(at: indexPath) is CourseListCVC else { return } - guard let selectedCells = collectionView.indexPathsForSelectedItems else { - self.deleteCourseButton.isEnabled = false - self.deleteCourseButton.setTitle(title: "삭제하기") - return } + guard let selectedCells = collectionView.indexPathsForSelectedItems else { return } guard let cell = collectionView.cellForItem(at: indexPath) as? CourseListCVC else { return } cell.selectCell(didSelect: false) if isEditMode { - self.deleteCourseButton.isEnabled = true - let countSelectCells = selectedCells.count - self.deleteCourseButton.setTitle(title: "삭제하기(\(countSelectCells))") - cell.selectCell(didSelect: false) - } else { - collectionView.deselectItem(at: indexPath, animated: true) - self.deleteCourseButton.setTitle(title: "삭제하기") cell.selectCell(didSelect: false) } + + let countSelectCells = selectedCells.count + if isEditMode { + self.deleteCourseButton.setTitle(title: "삭제하기(\(countSelectCells))") + } + self.deleteCourseButton.setEnabled(countSelectCells != 0) } } @@ -369,6 +367,7 @@ extension UploadedCourseInfoVC { let status = result.statusCode if 200..<300 ~= status { print("삭제 성공") + self.isEditMode.toggle() self.getUploadedCourseInfo() } if status >= 400 {