diff --git a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj index daad92f4..818d63f0 100644 --- a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj +++ b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj @@ -8,6 +8,9 @@ /* Begin PBXBuildFile section */ 0AEBD608F3973389E8E1C6D6 /* Pods_Runnect_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 015778D02D5CDE0838284CD7 /* Pods_Runnect_iOS.framework */; }; + A3BC2F2B2962C3D500198261 /* GoalRewardInfoVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3BC2F2A2962C3D500198261 /* GoalRewardInfoVC.swift */; }; + A3BC2F2D2962C3F200198261 /* ActivityRecordInfoVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3BC2F2C2962C3F200198261 /* ActivityRecordInfoVC.swift */; }; + A3BC2F2F2962C40A00198261 /* UploadedCourseInfoVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3BC2F2E2962C40A00198261 /* UploadedCourseInfoVC.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 */; }; CE17F0342961BEF800E1DED0 /* Pretendard-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = CE17F0302961BEF800E1DED0 /* Pretendard-Bold.otf */; }; @@ -75,6 +78,9 @@ /* Begin PBXFileReference section */ 015778D02D5CDE0838284CD7 /* Pods_Runnect_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runnect_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 3C3033C911343B5C57EB68E7 /* Pods-Runnect-iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runnect-iOS.debug.xcconfig"; path = "Target Support Files/Pods-Runnect-iOS/Pods-Runnect-iOS.debug.xcconfig"; sourceTree = ""; }; + A3BC2F2A2962C3D500198261 /* GoalRewardInfoVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoalRewardInfoVC.swift; sourceTree = ""; }; + A3BC2F2C2962C3F200198261 /* ActivityRecordInfoVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityRecordInfoVC.swift; sourceTree = ""; }; + A3BC2F2E2962C40A00198261 /* UploadedCourseInfoVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UploadedCourseInfoVC.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 = ""; }; CE17F0302961BEF800E1DED0 /* Pretendard-Bold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Pretendard-Bold.otf"; sourceTree = ""; }; @@ -182,6 +188,16 @@ name = Frameworks; sourceTree = ""; }; + A3BC2F292962C39F00198261 /* InfoVC */ = { + isa = PBXGroup; + children = ( + A3BC2F2A2962C3D500198261 /* GoalRewardInfoVC.swift */, + A3BC2F2C2962C3F200198261 /* ActivityRecordInfoVC.swift */, + A3BC2F2E2962C40A00198261 /* UploadedCourseInfoVC.swift */, + ); + path = InfoVC; + sourceTree = ""; + }; CE17F02E2961BEAE00E1DED0 /* Fonts */ = { isa = PBXGroup; children = ( @@ -297,6 +313,7 @@ CE17F0452961C3DD00E1DED0 /* VC */ = { isa = PBXGroup; children = ( + A3BC2F292962C39F00198261 /* InfoVC */, CEEC6B3F2961C55000D00E1E /* MyPageVC.swift */, ); path = VC; @@ -741,6 +758,7 @@ buildActionMask = 2147483647; files = ( CE665604295D91B100C64E12 /* makeAlert.swift in Sources */, + A3BC2F2F2962C40A00198261 /* UploadedCourseInfoVC.swift in Sources */, CE6655EA295D88B200C64E12 /* UITabBar+.swift in Sources */, CEC2A68729629B9B00160BF7 /* SignInVC.swift in Sources */, CE665602295D918000C64E12 /* JsonCoder.swift in Sources */, @@ -750,6 +768,7 @@ CE6655CD295D856300C64E12 /* KeyPathFindable.swift in Sources */, CE6655E4295D884600C64E12 /* UILabel+.swift in Sources */, CE6655FA295D90E000C64E12 /* applyShadow.swift in Sources */, + A3BC2F2B2962C3D500198261 /* GoalRewardInfoVC.swift in Sources */, CE665606295D91C500C64E12 /* makeVibrate.swift in Sources */, CE66560A295D924A00C64E12 /* Result+.swift in Sources */, CE66560E295D92A500C64E12 /* setStatusBarBackgroundColor.swift in Sources */, @@ -793,6 +812,7 @@ CE6655CA295D84DD00C64E12 /* UserDefaultKeyList.swift in Sources */, CE6655F2295D894D00C64E12 /* UIView+.swift in Sources */, CE665600295D915D00C64E12 /* getClassName.swift in Sources */, + A3BC2F2D2962C3F200198261 /* ActivityRecordInfoVC.swift in Sources */, CE6655FC295D90F500C64E12 /* calculatePastTime.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Runnect-iOS/Runnect-iOS/Global/Literal/ColorLiterals.swift b/Runnect-iOS/Runnect-iOS/Global/Literal/ColorLiterals.swift index 0fc2614a..dedf2a48 100644 --- a/Runnect-iOS/Runnect-iOS/Global/Literal/ColorLiterals.swift +++ b/Runnect-iOS/Runnect-iOS/Global/Literal/ColorLiterals.swift @@ -28,6 +28,10 @@ extension UIColor { return UIColor(hex: "#ECECEC") } + static var g5: UIColor { + return UIColor(hex: "#F3F3F3") + } + static var m1: UIColor { return UIColor(hex: "#593EEC") } diff --git a/Runnect-iOS/Runnect-iOS/Global/Supports/SceneDelegate.swift b/Runnect-iOS/Runnect-iOS/Global/Supports/SceneDelegate.swift index ac34efc3..b1a5c3a4 100644 --- a/Runnect-iOS/Runnect-iOS/Global/Supports/SceneDelegate.swift +++ b/Runnect-iOS/Runnect-iOS/Global/Supports/SceneDelegate.swift @@ -16,7 +16,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { guard let windowScene = (scene as? UIWindowScene) else { return } let window = UIWindow(windowScene: windowScene) - window.rootViewController = UINavigationController(rootViewController: SplashVC()) + window.rootViewController = TabBarController() self.window = window window.makeKeyAndVisible() } diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingHomeVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingHomeVC.swift index 69bedd9f..9da09656 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingHomeVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingHomeVC.swift @@ -38,3 +38,5 @@ final class CourseDrawingHomeVC: UIViewController, CustomNavigationBarDelegate { print(text) } } + + diff --git a/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/ActivityRecordInfoVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/ActivityRecordInfoVC.swift new file mode 100644 index 00000000..a51dbc40 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/ActivityRecordInfoVC.swift @@ -0,0 +1,23 @@ +// +// ActivityRecordInfoVC.swift +// Runnect-iOS +// +// Created by 몽이 누나 on 2023/01/02. +// + +import UIKit + +final class ActivityRecordInfoVC: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + setUI() + // Do any additional setup after loading the view. + } +} + +extension ActivityRecordInfoVC { + private func setUI() { + view.backgroundColor = .w1 + } +} diff --git a/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/GoalRewardInfoVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/GoalRewardInfoVC.swift new file mode 100644 index 00000000..6922d4dc --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/GoalRewardInfoVC.swift @@ -0,0 +1,23 @@ +// +// GoalRewardInfoVC.swift +// Runnect-iOS +// +// Created by 몽이 누나 on 2023/01/02. +// + +import UIKit + +final class GoalRewardInfoVC: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + setUI() + // Do any additional setup after loading the view. + } +} + +extension GoalRewardInfoVC { + private func setUI() { + view.backgroundColor = .w1 + } +} diff --git a/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/UploadedCourseInfoVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/UploadedCourseInfoVC.swift new file mode 100644 index 00000000..fec5bd0c --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/InfoVC/UploadedCourseInfoVC.swift @@ -0,0 +1,23 @@ +// +// UploadedCourseInfoVC.swift +// Runnect-iOS +// +// Created by 몽이 누나 on 2023/01/02. +// + +import UIKit + +final class UploadedCourseInfoVC: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + setUI() + // Do any additional setup after loading the view. + } +} + +extension UploadedCourseInfoVC { + private func setUI() { + view.backgroundColor = .w1 + } +} diff --git a/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/MyPageVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/MyPageVC.swift index 2d48c178..03b13596 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/MyPageVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/MyPageVC.swift @@ -6,11 +6,288 @@ // import UIKit +import SnapKit +import Then final class MyPageVC: UIViewController { + + // MARK: - UI Components + + private lazy var navibar = CustomNavigationBar(self, type: .title).setTitle("마이페이지") + private let myProfileView = UIView() + private let myRunningProgressView = UIView() + private let firstDivideView = UIView() + private let secondDivideView = UIView() + private let thirdDivideView = UIView() + + private let myProfileImage = UIImageView().then { + $0.image = ImageLiterals.imgStampR2 + } + + private let myProfileNameLabel = UILabel().then { + $0.text = "말랑콩떡" + $0.textColor = .m1 + $0.font = .h4 + } + + private let myProfileEditButton = UIButton(type: .system).then { + $0.setImage(ImageLiterals.icEdit, for: .normal) + $0.setTitle("수정하기", for: .normal) + $0.titleLabel?.font = .b7 + $0.setTitleColor(.m2, for: .normal) + $0.tintColor = .m2 + $0.layer.borderWidth = 1 + $0.layer.borderColor = UIColor.m2.cgColor + $0.layer.cornerRadius = 14 + $0.imageEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 4) + } + + private let myRunningLevelLavel = UILabel().then { + $0.text = "LV 3" + $0.textColor = .g1 + $0.font = .h5 + } + + private let myRunningProgressBar = UIProgressView(progressViewStyle: .bar).then { + $0.translatesAutoresizingMaskIntoConstraints = false + $0.setProgress(0.25, animated: false) + $0.progressTintColor = .m1 + $0.trackTintColor = .m3 + $0.layer.cornerRadius = 6 + $0.clipsToBounds = true + $0.layer.sublayers![1].cornerRadius = 6 + $0.subviews[1].clipsToBounds = true + } + + private let myRunnigProgressPercentLabel = UILabel().then { + let attributedString = NSMutableAttributedString(string: "25", attributes: [.font: UIFont.b5, .foregroundColor: UIColor.g1]) + attributedString.append(NSAttributedString(string: " /100", attributes: [.font: UIFont.b5, .foregroundColor: UIColor.g2])) + $0.attributedText = attributedString + } + + private lazy var goalRewardInfoView = makeInfoView(title: "목표 보상").then { + let tap = UITapGestureRecognizer(target: self, action: #selector(self.touchUpGoalRewardInfoView)) + $0.addGestureRecognizer(tap) + } + + private lazy var activityRecordInfoView = makeInfoView(title: "활동 기록").then { + let tap = UITapGestureRecognizer(target: self, action: #selector(self.touchUpActivityRecordInfoView)) + $0.addGestureRecognizer(tap) + } + + private lazy var uploadedCourseInfoView = makeInfoView(title: "업로드한 코스").then { + let tap = UITapGestureRecognizer(target: self, action: #selector(self.uploadedCourseRecordInfoView)) + $0.addGestureRecognizer(tap) + } + // MARK: - View Life Cycle + override func viewDidLoad() { super.viewDidLoad() - view.backgroundColor = .m2 + setNavigationBar() + setUI() + setLayout() + } +} + +// MARK: - Methods + +extension MyPageVC { + private func makeInfoView(title: String) -> UIView { + let containerView = UIView() + let icStar = UIImageView().then { + $0.image = ImageLiterals.icStar + } + + let label = UILabel().then { + $0.text = title + $0.textColor = .g1 + $0.font = .b2 + } + + let icArrowRight = UIImageView().then { + $0.image = ImageLiterals.icArrowRight + } + + containerView.addSubviews(icStar, label, icArrowRight) + + icStar.snp.makeConstraints { make in + make.top.equalToSuperview().offset(22) + make.leading.equalToSuperview().offset(17) + make.width.equalTo(14) + make.height.equalTo(14) + } + + label.snp.makeConstraints { make in + make.top.equalToSuperview().offset(21) + make.leading.equalTo(icStar.snp.trailing).offset(8) + } + + icArrowRight.snp.makeConstraints { make in + make.top.equalToSuperview().offset(18) + make.trailing.equalToSuperview().inset(8) + } + + return containerView + } + + private func pushToGoalRewardInfoVC() { + let goalRewardInfoVC = GoalRewardInfoVC() + self.navigationController?.pushViewController(goalRewardInfoVC, animated: true) + } + + private func pushToActivityRecordInfoVC() { + let activityRecordInfoVC = ActivityRecordInfoVC() + self.navigationController?.pushViewController(activityRecordInfoVC, animated: true) + } + + private func pushToUploadedCourseInfoVC() { + let uploadedCourseInfoVC = ActivityRecordInfoVC() + self.navigationController?.pushViewController(uploadedCourseInfoVC, animated: true) + } +} + +// MARK: - @objc Function + +extension MyPageVC { + @objc + private func touchUpGoalRewardInfoView() { + pushToGoalRewardInfoVC() + } + + @objc + private func touchUpActivityRecordInfoView() { + pushToActivityRecordInfoVC() + } + + @objc + private func uploadedCourseRecordInfoView() { + pushToActivityRecordInfoVC() + } +} + +// MARK: - UI & Layout + +extension MyPageVC { + private func setNavigationBar() { + view.addSubview(navibar) + + navibar.snp.makeConstraints { make in + make.leading.top.trailing.equalTo(view.safeAreaLayoutGuide) + make.height.equalTo(48) + } + } + + private func setUI() { + view.backgroundColor = .w1 + myProfileView.backgroundColor = .m3 + firstDivideView.backgroundColor = .g5 + secondDivideView.backgroundColor = .g4 + thirdDivideView.backgroundColor = .g4 + } + + private func setLayout() { + view.addSubviews(myProfileView, myRunningProgressView, firstDivideView, + goalRewardInfoView, secondDivideView, activityRecordInfoView, + thirdDivideView, uploadedCourseInfoView) + + myProfileView.snp.makeConstraints { make in + make.top.equalTo(navibar.snp.bottom).offset(6) + make.leading.trailing.equalToSuperview() + make.height.equalTo(84) + } + + setMyProfileLayout() + setRunningProgressLayout() + + firstDivideView.snp.makeConstraints { make in + make.top.equalTo(myRunningProgressView.snp.bottom).offset(34) + make.leading.trailing.equalToSuperview() + make.height.equalTo(10) + } + + setInfoButtonLayout() + } + + private func setMyProfileLayout() { + myProfileView.addSubviews(myProfileImage, myProfileNameLabel, myProfileEditButton) + + myProfileImage.snp.makeConstraints { make in + make.top.equalToSuperview().offset(11) + make.leading.equalToSuperview().offset(23) + make.width.equalTo(63) + make.height.equalTo(63) + } + + myProfileNameLabel.snp.makeConstraints { make in + make.top.equalToSuperview().offset(32) + make.leading.equalTo(myProfileImage.snp.trailing).offset(10) + } + + myProfileEditButton.snp.makeConstraints { make in + make.top.equalToSuperview().offset(29) + make.trailing.equalToSuperview().inset(16) + make.width.equalTo(78) + make.height.equalTo(28) + } + + myRunningProgressView.snp.makeConstraints { make in + make.top.equalTo(myProfileView.snp.bottom).offset(18) + make.leading.trailing.equalToSuperview().inset(16) + make.height.equalTo(55) + } + } + + private func setRunningProgressLayout() { + myRunningProgressView.addSubviews(myRunningLevelLavel, myRunningProgressBar, + myRunnigProgressPercentLabel) + + myRunningLevelLavel.snp.makeConstraints { make in + make.top.equalToSuperview() + make.leading.equalToSuperview().offset(1) + } + + myRunningProgressBar.snp.makeConstraints { make in + make.top.equalTo(myRunningLevelLavel.snp.bottom).offset(6) + make.leading.trailing.equalToSuperview() + make.height.equalTo(11) + } + + myRunnigProgressPercentLabel.snp.makeConstraints { make in + make.bottom.equalToSuperview() + make.trailing.equalToSuperview() + } + } + + private func setInfoButtonLayout() { + goalRewardInfoView.snp.makeConstraints { make in + make.top.equalTo(firstDivideView.snp.bottom) + make.leading.trailing.equalToSuperview() + make.height.equalTo(60) + } + + secondDivideView.snp.makeConstraints { make in + make.top.equalTo(goalRewardInfoView.snp.bottom).offset(1) + make.leading.trailing.equalToSuperview() + make.height.equalTo(0.5) + } + + activityRecordInfoView.snp.makeConstraints { make in + make.top.equalTo(secondDivideView.snp.bottom) + make.leading.trailing.equalToSuperview() + make.height.equalTo(60) + } + + thirdDivideView.snp.makeConstraints { make in + make.top.equalTo(activityRecordInfoView.snp.bottom).offset(1) + make.leading.trailing.equalToSuperview() + make.height.equalTo(0.5) + } + + uploadedCourseInfoView.snp.makeConstraints { make in + make.top.equalTo(thirdDivideView.snp.bottom) + make.leading.trailing.equalToSuperview() + make.height.equalTo(60) + } } } diff --git a/Runnect-iOS/Runnect-iOS/Presentation/TabBar/TaBarController.swift b/Runnect-iOS/Runnect-iOS/Presentation/TabBar/TaBarController.swift index bcebc2ea..01657dff 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/TabBar/TaBarController.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/TabBar/TaBarController.swift @@ -46,7 +46,7 @@ extension TabBarController { let myPageNVC = templateNavigationController(title: "마이페이지", unselectedImage: ImageLiterals.icMypage, selectedImage: ImageLiterals.icMypageFill, - rootViewController: CourseStorageVC()) + rootViewController: MyPageVC()) viewControllers = [courseDrawingNVC, courseStorageNVC, courseDiscoveryNVC, myPageNVC] }