diff --git a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj index a278555d..47c3013b 100644 --- a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj +++ b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj @@ -15,6 +15,8 @@ A3BC2F34296303A600198261 /* GoalRewardInfoCVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3BC2F33296303A600198261 /* GoalRewardInfoCVC.swift */; }; A3BC2F382963CE3700198261 /* ActivityRecordInfoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3BC2F372963CE3700198261 /* ActivityRecordInfoModel.swift */; }; A3BC2F3A2963D0ED00198261 /* ActivityRecordInfoTVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3BC2F392963D0ED00198261 /* ActivityRecordInfoTVC.swift */; }; + A3BC2F3D296468E500198261 /* UploadedCourseInfoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3BC2F3C296468E500198261 /* UploadedCourseInfoModel.swift */; }; + A3BC2F3F2964706100198261 /* UploadedCourseInfoCVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3BC2F3E2964706100198261 /* UploadedCourseInfoCVC.swift */; }; CE0D9FD329648DA300CEB5CD /* CustomAlertVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE0D9FD229648DA300CEB5CD /* CustomAlertVC.swift */; }; CE17F02D2961BBA100E1DED0 /* ColorLiterals.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE17F02C2961BBA100E1DED0 /* ColorLiterals.swift */; }; CE17F0332961BEF800E1DED0 /* Pretendard-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = CE17F02F2961BEF800E1DED0 /* Pretendard-Medium.otf */; }; @@ -99,6 +101,8 @@ A3BC2F33296303A600198261 /* GoalRewardInfoCVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoalRewardInfoCVC.swift; sourceTree = ""; }; A3BC2F372963CE3700198261 /* ActivityRecordInfoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityRecordInfoModel.swift; sourceTree = ""; }; A3BC2F392963D0ED00198261 /* ActivityRecordInfoTVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityRecordInfoTVC.swift; sourceTree = ""; }; + A3BC2F3C296468E500198261 /* UploadedCourseInfoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UploadedCourseInfoModel.swift; sourceTree = ""; }; + A3BC2F3E2964706100198261 /* UploadedCourseInfoCVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UploadedCourseInfoCVC.swift; sourceTree = ""; }; CE0D9FD229648DA300CEB5CD /* CustomAlertVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomAlertVC.swift; sourceTree = ""; }; CE17F02C2961BBA100E1DED0 /* ColorLiterals.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorLiterals.swift; sourceTree = ""; }; CE17F02F2961BEF800E1DED0 /* Pretendard-Medium.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Pretendard-Medium.otf"; sourceTree = ""; }; @@ -218,6 +222,7 @@ A3BC2F292962C39F00198261 /* InfoVC */ = { isa = PBXGroup; children = ( + A3BC2F3B2964671D00198261 /* UploadedCourseInfoCollectionView */, A3BC2F362963CD2100198261 /* ActivityRecordInfoTableView */, A3BC2F302962E08400198261 /* GoalRewardInfoCollectionView */, A3BC2F2A2962C3D500198261 /* GoalRewardInfoVC.swift */, @@ -245,6 +250,15 @@ path = ActivityRecordInfoTableView; sourceTree = ""; }; + A3BC2F3B2964671D00198261 /* UploadedCourseInfoCollectionView */ = { + isa = PBXGroup; + children = ( + A3BC2F3C296468E500198261 /* UploadedCourseInfoModel.swift */, + A3BC2F3E2964706100198261 /* UploadedCourseInfoCVC.swift */, + ); + path = UploadedCourseInfoCollectionView; + sourceTree = ""; + }; CE17F02E2961BEAE00E1DED0 /* Fonts */ = { isa = PBXGroup; children = ( @@ -855,9 +869,11 @@ CE6655EE295D88E600C64E12 /* UITextField+.swift in Sources */, CE6655F8295D90CF00C64E12 /* adjusted+.swift in Sources */, CE4545CB295D7AF4003201E1 /* SceneDelegate.swift in Sources */, + A3BC2F3F2964706100198261 /* UploadedCourseInfoCVC.swift in Sources */, CE6655FE295D912300C64E12 /* calculateTopInset.swift in Sources */, CEEC6B492961C5E200D00E1E /* SplashVC.swift in Sources */, CE6655D0295D85FF00C64E12 /* CancelBag.swift in Sources */, + A3BC2F3D296468E500198261 /* UploadedCourseInfoModel.swift in Sources */, CE6655DC295D873500C64E12 /* UIButton+.swift in Sources */, CE6655D4295D865B00C64E12 /* Publisher+UIControl.swift in Sources */, CE0D9FD329648DA300CEB5CD /* CustomAlertVC.swift in Sources */, diff --git a/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/GoalRewardInfoCollectionView/GoalRewardInfoCVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/GoalRewardInfoCollectionView/GoalRewardInfoCVC.swift index 6fbe6d0e..44766f52 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/GoalRewardInfoCollectionView/GoalRewardInfoCVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/GoalRewardInfoCollectionView/GoalRewardInfoCVC.swift @@ -15,7 +15,6 @@ final class GoalRewardInfoCVC: UICollectionViewCell { // MARK: - UI Components - private let containerView = UIView() private let stampImageView = UIImageView() private let stampStandardLabel = UILabel().then { $0.textColor = .g1 diff --git a/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/GoalRewardInfoVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/GoalRewardInfoVC.swift index 77cc6cea..9b7f69b4 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/GoalRewardInfoVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/GoalRewardInfoVC.swift @@ -11,7 +11,7 @@ import Then final class GoalRewardInfoVC: UIViewController { - // MARK: - Variables + // MARK: - Properties var stampList: [GoalRewardInfoModel] = [ GoalRewardInfoModel(stampImg: ImageLiterals.imgStampC1, stampStandard: "그리기 스타터"), @@ -55,7 +55,6 @@ final class GoalRewardInfoVC: UIViewController { layout.scrollDirection = .vertical let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) - collectionView.translatesAutoresizingMaskIntoConstraints = false collectionView.isScrollEnabled = true collectionView.showsVerticalScrollIndicator = false collectionView.delegate = self @@ -144,10 +143,6 @@ extension GoalRewardInfoVC: UICollectionViewDelegateFlowLayout { return stampLineSpacing } - func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat { - return stampLineSpacing - } - func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets { return stampInset } diff --git a/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/UploadedCourseInfoCollectionView/UploadedCourseInfoCVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/UploadedCourseInfoCollectionView/UploadedCourseInfoCVC.swift new file mode 100644 index 00000000..cc844ef1 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/UploadedCourseInfoCollectionView/UploadedCourseInfoCVC.swift @@ -0,0 +1,82 @@ +// +// UploadedCourseInfoCVC.swift +// Runnect-iOS +// +// Created by 몽이 누나 on 2023/01/03. +// + +import UIKit +import SnapKit +import Then + +final class UploadedCourseInfoCVC: UICollectionViewCell { + + // MARK: - UI Components + + private let uploadedCourseMapImage = UIImageView().then { + $0.layer.cornerRadius = 5 + } + + private let uploadedCourseTitleLabel = UILabel().then { + $0.textColor = .g1 + $0.font = .b4 + } + + private let uploadedCoursePlaceLabel = UILabel().then { + $0.textColor = .g2 + $0.font = .b6 + } + + // MARK: - Life Cycles + + override init(frame: CGRect) { + super.init(frame: frame) + setUI() + setLayout() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} + +extension UploadedCourseInfoCVC { + + // MARK: - Layout Helpers + + private func setUI() { + uploadedCourseMapImage.backgroundColor = .g3 + } + + private func setLayout() { + contentView.addSubviews(uploadedCourseMapImage, uploadedCourseTitleLabel, uploadedCoursePlaceLabel) + + contentView.snp.makeConstraints { make in + make.top.leading.equalToSuperview() + } + + uploadedCourseMapImage.snp.makeConstraints { make in + make.top.leading.equalToSuperview() + make.width.equalTo(174) + make.height.equalTo(124) + } + + uploadedCourseTitleLabel.snp.makeConstraints { make in + make.top.equalTo(uploadedCourseMapImage.snp.bottom).offset(7) + make.leading.equalToSuperview() + } + + uploadedCoursePlaceLabel.snp.makeConstraints { make in + make.top.equalTo(uploadedCourseTitleLabel.snp.bottom).offset(5) + make.leading.equalToSuperview() + } + } + + // MARK: - General Helpers + + func dataBind(model: UploadedCourseInfoModel) { + uploadedCourseTitleLabel.text = model.title + uploadedCoursePlaceLabel.text = model.place + } + +} diff --git a/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/UploadedCourseInfoCollectionView/UploadedCourseInfoModel.swift b/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/UploadedCourseInfoCollectionView/UploadedCourseInfoModel.swift new file mode 100644 index 00000000..cdb597b7 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/UploadedCourseInfoCollectionView/UploadedCourseInfoModel.swift @@ -0,0 +1,14 @@ +// +// UploadedCourseInfoModel.swift +// Runnect-iOS +// +// Created by 몽이 누나 on 2023/01/03. +// + +import Foundation +import UIKit + +struct UploadedCourseInfoModel { + let title: String + let place: String +} 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 fec5bd0c..35426c86 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/UploadedCourseInfoVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/UploadedCourseInfoVC.swift @@ -6,18 +6,124 @@ // import UIKit +import SnapKit +import Then final class UploadedCourseInfoVC: UIViewController { + + // MARK: - Properties + + var UploadedCourseList: [UploadedCourseInfoModel] = [ + UploadedCourseInfoModel(title: "행복한 날들", place: "수원시 장안구"), + UploadedCourseInfoModel(title: "몽이랑 산책", place: "수원시 장안구"), + UploadedCourseInfoModel(title: "패스트파이브", place: "수원시 장안구"), + UploadedCourseInfoModel(title: "행복한 날들", place: "수원시 장안구"), + UploadedCourseInfoModel(title: "몽이랑 산책", place: "수원시 장안구"), + UploadedCourseInfoModel(title: "패스트파이브", place: "수원시 장안구"), + UploadedCourseInfoModel(title: "행복한 날들", place: "수원시 장안구"), + UploadedCourseInfoModel(title: "몽이랑 산책", place: "수원시 장안구"), + UploadedCourseInfoModel(title: "패스트파이브", place: "수원시 장안구") + ] + + // MARK: - Constants + + final let uploadedCourseInset: UIEdgeInsets = UIEdgeInsets(top: 16, left: 16, bottom: 0, right: 16) + final let uploadedCourseLineSpacing: CGFloat = 20 + final let uploadedCourseItemSpacing: CGFloat = 10 + final let uplodaedCourseCellHeight: CGFloat = 124 + // MARK: - UI Components + + private lazy var navibar = CustomNavigationBar(self, type: .titleWithLeftButton).setTitle("업로드한 코스") + + private lazy var UploadedCourseInfoCollectionView: UICollectionView = { + let layout = UICollectionViewFlowLayout() + layout.scrollDirection = .vertical + + let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) + collectionView.isScrollEnabled = true + collectionView.showsVerticalScrollIndicator = false + collectionView.delegate = self + collectionView.dataSource = self + + return collectionView + }() + + // MARK: - View Life Cycle + override func viewDidLoad() { super.viewDidLoad() + setNavigationBar() setUI() - // Do any additional setup after loading the view. + setLayout() + register() } } extension UploadedCourseInfoVC { + + // MARK: - Layout Helpers + + private func setNavigationBar() { + view.addSubview(navibar) + + navibar.snp.makeConstraints { make in + make.top.leading.trailing.equalTo(view.safeAreaLayoutGuide) + make.height.equalTo(48) + } + } + private func setUI() { view.backgroundColor = .w1 + UploadedCourseInfoCollectionView.backgroundColor = .w1 + } + + private func setLayout() { + view.addSubview(UploadedCourseInfoCollectionView) + + UploadedCourseInfoCollectionView.snp.makeConstraints { make in + make.top.equalTo(navibar.snp.bottom) + make.leading.trailing.equalTo(view.safeAreaLayoutGuide) + make.bottom.equalToSuperview() + } + } + + // MARK: - General Helpers + + private func register() { + UploadedCourseInfoCollectionView.register(UploadedCourseInfoCVC.self, + forCellWithReuseIdentifier: UploadedCourseInfoCVC.className) + } +} + +// MARK: - UICollectionViewDelegateFlowLayout + +extension UploadedCourseInfoVC: UICollectionViewDelegateFlowLayout { + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { + let screenWidth = UIScreen.main.bounds.width + let doubleCellWidth = screenWidth - uploadedCourseInset.left - uploadedCourseInset.right - uploadedCourseItemSpacing + return CGSize(width: doubleCellWidth / 2, height: 164) + } + + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { + return uploadedCourseLineSpacing + } + + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets { + return uploadedCourseInset + } +} + +// MARK: - UICollectionViewDataSource + +extension UploadedCourseInfoVC: UICollectionViewDataSource { + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return UploadedCourseList.count + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + guard let uploadedCourseCell = collectionView.dequeueReusableCell(withReuseIdentifier: UploadedCourseInfoCVC.className, for: indexPath) as? UploadedCourseInfoCVC else { return UICollectionViewCell()} + uploadedCourseCell.dataBind(model: UploadedCourseList[indexPath.item]) + return uploadedCourseCell } } diff --git a/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/MyPageVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/MyPageVC.swift index 933123bd..597713e6 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/MyPageVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/MyPageVC.swift @@ -80,7 +80,7 @@ final class MyPageVC: UIViewController { $0.addGestureRecognizer(tap) } - // MARK: - + // MARK: - View Life Cycle override func viewDidLoad() { super.viewDidLoad() @@ -142,7 +142,7 @@ extension MyPageVC { } private func pushToUploadedCourseInfoVC() { - let uploadedCourseInfoVC = ActivityRecordInfoVC() + let uploadedCourseInfoVC = UploadedCourseInfoVC() self.navigationController?.pushViewController(uploadedCourseInfoVC, animated: true) } } @@ -162,7 +162,7 @@ extension MyPageVC { @objc private func uploadedCourseRecordInfoView() { - pushToActivityRecordInfoVC() + pushToUploadedCourseInfoVC() } }