diff --git a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj index cdc5fe6f..a278555d 100644 --- a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj +++ b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj @@ -15,6 +15,7 @@ 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 */; }; + 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 */; }; CE17F0342961BEF800E1DED0 /* Pretendard-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = CE17F0302961BEF800E1DED0 /* Pretendard-Bold.otf */; }; @@ -98,6 +99,7 @@ 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 = ""; }; + 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 = ""; }; CE17F0302961BEF800E1DED0 /* Pretendard-Bold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Pretendard-Bold.otf"; sourceTree = ""; }; @@ -583,6 +585,7 @@ CEC2A6882962ADB900160BF7 /* MapView */, CEEC6B4A2961D89700D00E1E /* CustomNavigationBar.swift */, CEC2A6842961F92C00160BF7 /* CustomButton.swift */, + CE0D9FD229648DA300CEB5CD /* CustomAlertVC.swift */, ); path = UIComponents; sourceTree = ""; @@ -857,6 +860,7 @@ CE6655D0295D85FF00C64E12 /* CancelBag.swift in Sources */, CE6655DC295D873500C64E12 /* UIButton+.swift in Sources */, CE6655D4295D865B00C64E12 /* Publisher+UIControl.swift in Sources */, + CE0D9FD329648DA300CEB5CD /* CustomAlertVC.swift in Sources */, CEB841702963360800BF8080 /* CountDownVC.swift in Sources */, CE6655EC295D88D000C64E12 /* UITableView+.swift in Sources */, CEEC6B3A2961C4F300D00E1E /* CourseDrawingHomeVC.swift in Sources */, diff --git a/Runnect-iOS/Runnect-iOS/Global/Literal/ImageLiterals.swift b/Runnect-iOS/Runnect-iOS/Global/Literal/ImageLiterals.swift index 0cedee41..87fed01a 100644 --- a/Runnect-iOS/Runnect-iOS/Global/Literal/ImageLiterals.swift +++ b/Runnect-iOS/Runnect-iOS/Global/Literal/ImageLiterals.swift @@ -6,6 +6,7 @@ // import UIKit +import NMapsMap enum ImageLiterals { // icon @@ -37,6 +38,8 @@ enum ImageLiterals { static var icTime: UIImage { .load(named: "ic_time") } static var icLocationPoint: UIImage { .load(named: "ic_location_point") } static var icAlert: UIImage { .load(named: "ic_alert") } + static var icLocationOverlay: UIImage { .load(named: "ic_location_overlay") } + // img static var imgBackground: UIImage { .load(named: "img_background") } static var imgLogo: UIImage { .load(named: "img_logo") } @@ -57,6 +60,7 @@ enum ImageLiterals { static var imgStamp: UIImage { .load(named: "img_stamp") } static var imgStorage: UIImage { .load(named: "img_storage") } static var imgLock: UIImage { .load(named: "img_lock") } + static var imgTelescope: UIImage { .load(named: "img_telescope") } } extension UIImage { diff --git a/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_location_overlay.imageset/Contents.json b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_location_overlay.imageset/Contents.json new file mode 100644 index 00000000..4b62cfbe --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_location_overlay.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "point 1.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "point 1@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "point 1@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_location_overlay.imageset/point 1.png b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_location_overlay.imageset/point 1.png new file mode 100644 index 00000000..d3dd771b Binary files /dev/null and b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_location_overlay.imageset/point 1.png differ diff --git a/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_location_overlay.imageset/point 1@2x.png b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_location_overlay.imageset/point 1@2x.png new file mode 100644 index 00000000..5e0016f9 Binary files /dev/null and b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_location_overlay.imageset/point 1@2x.png differ diff --git a/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_location_overlay.imageset/point 1@3x.png b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_location_overlay.imageset/point 1@3x.png new file mode 100644 index 00000000..afa5ced3 Binary files /dev/null and b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_location_overlay.imageset/point 1@3x.png differ diff --git a/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/img_telescope.imageset/Contents.json b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/img_telescope.imageset/Contents.json new file mode 100644 index 00000000..2c655e10 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/img_telescope.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "draw_img_telescope 2.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "draw_img_telescope 2@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "draw_img_telescope 2@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/img_telescope.imageset/draw_img_telescope 2.png b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/img_telescope.imageset/draw_img_telescope 2.png new file mode 100644 index 00000000..236fc44d Binary files /dev/null and b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/img_telescope.imageset/draw_img_telescope 2.png differ diff --git a/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/img_telescope.imageset/draw_img_telescope 2@2x.png b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/img_telescope.imageset/draw_img_telescope 2@2x.png new file mode 100644 index 00000000..7ba81825 Binary files /dev/null and b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/img_telescope.imageset/draw_img_telescope 2@2x.png differ diff --git a/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/img_telescope.imageset/draw_img_telescope 2@3x.png b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/img_telescope.imageset/draw_img_telescope 2@3x.png new file mode 100644 index 00000000..aed34347 Binary files /dev/null and b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/img_telescope.imageset/draw_img_telescope 2@3x.png differ diff --git a/Runnect-iOS/Runnect-iOS/Global/UIComponents/CustomAlertVC.swift b/Runnect-iOS/Runnect-iOS/Global/UIComponents/CustomAlertVC.swift new file mode 100644 index 00000000..0e887353 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/UIComponents/CustomAlertVC.swift @@ -0,0 +1,120 @@ +// +// CustomAlertVC.swift +// Runnect-iOS +// +// Created by sejin on 2023/01/04. +// + +import UIKit +import Combine + +final class CustomAlertVC: UIViewController { + + // MARK: - Properties + + var leftButtonTapped: Driver { + leftButton.publisher(for: .touchUpInside) + .map { _ in } + .asDriver() + } + + var rightButtonTapped: Driver { + rightButton.publisher(for: .touchUpInside) + .map { _ in } + .asDriver() + } + + // MARK: - UI Components + + private let alertView = UIView() + private let alertImageView = UIImageView().then { + $0.image = ImageLiterals.imgTelescope + } + private let contentsLabel = UILabel().then { + $0.text = "코스를 만들었어요!" + $0.font = .h5 + $0.textColor = .g2 + $0.textAlignment = .center + } + + private let leftButton = CustomButton(title: "보관함 가기") + .setColor(bgColor: .m3, disableColor: .m3, textColor: .m1) + + private let rightButton = CustomButton(title: "바로 달리기") + + private lazy var buttonStackView = UIStackView(arrangedSubviews: [leftButton, rightButton]) + .then { + $0.spacing = 10 + $0.distribution = .fillEqually + } + + // MARK: - View Life Cycle + + override func viewDidLoad() { + super.viewDidLoad() + self.setUI() + self.setLayout() + } +} + +// MARK: - Methods + +extension CustomAlertVC { + /// conentsLabel의 텍스트 변경 + @discardableResult + public func setTitle(_ title: String) -> Self { + self.contentsLabel.text = title + return self + } + + /// 좌측 버튼의 텍스트 변경 + @discardableResult + public func setLeftButtonTitle(_ title: NSAttributedString) -> Self { + self.leftButton.changeTitle(attributedString: title) + return self + } + + /// 우측 버튼의 텍스트 변경 + @discardableResult + public func setRightButtonTitle(_ title: NSAttributedString) -> Self { + self.rightButton.changeTitle(attributedString: title) + return self + } +} + +// MARK: - UI & Layout + +extension CustomAlertVC { + private func setUI() { + view.backgroundColor = .black.withAlphaComponent(0.8) + alertView.backgroundColor = .w1 + alertView.layer.cornerRadius = 20 + } + + private func setLayout() { + view.addSubviews(alertView) + alertView.addSubviews(alertImageView, contentsLabel, buttonStackView) + + alertView.snp.makeConstraints { make in + make.center.equalTo(view.safeAreaLayoutGuide) + make.leading.trailing.equalTo(view.safeAreaLayoutGuide).inset(31) + } + + alertImageView.snp.makeConstraints { make in + make.top.equalToSuperview().inset(38) + make.centerX.equalToSuperview() + } + + contentsLabel.snp.makeConstraints { make in + make.top.equalTo(alertImageView.snp.bottom).offset(24) + make.centerX.equalToSuperview() + } + + buttonStackView.snp.makeConstraints { make in + make.top.equalTo(contentsLabel.snp.bottom).offset(26) + make.leading.trailing.equalToSuperview().inset(14) + make.height.equalTo(44) + make.bottom.equalToSuperview().inset(25) + } + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/UIComponents/CustomButton.swift b/Runnect-iOS/Runnect-iOS/Global/UIComponents/CustomButton.swift index 74eb3cbc..9422bfa9 100644 --- a/Runnect-iOS/Runnect-iOS/Global/UIComponents/CustomButton.swift +++ b/Runnect-iOS/Runnect-iOS/Global/UIComponents/CustomButton.swift @@ -40,13 +40,13 @@ extension CustomButton { /// 버튼의 backgroundColor, textColor 변경 @discardableResult - public func setColor(bgColor: UIColor, disableColor: UIColor, _ textColor: UIColor = .white) -> Self { + public func setColor(bgColor: UIColor, disableColor: UIColor, textColor: UIColor = .white) -> Self { self.setBackgroundColor(bgColor, for: .normal) self.setBackgroundColor(disableColor, for: .disabled) self.setAttributedTitle( NSAttributedString( string: self.titleLabel?.text ?? "", - attributes: [.font: UIFont.h2, .foregroundColor: textColor]), + attributes: [.font: UIFont.h5, .foregroundColor: textColor]), for: .normal) return self diff --git a/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift b/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift index 135aad29..0886b764 100644 --- a/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift +++ b/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift @@ -35,6 +35,7 @@ final class RNMapView: UIView { [self.startMarker.position] + self.markers.map { $0.position } } private var bottomPadding: CGFloat = 0 + private let locationOverlayIcon = NMFOverlayImage(image: ImageLiterals.icLocationOverlay) // MARK: - UI Components @@ -63,6 +64,7 @@ final class RNMapView: UIView { setMap() getLocationAuth() setPathOverlay() + setLocationOverlay() } required init?(coder: NSCoder) { @@ -85,6 +87,7 @@ extension RNMapView { @discardableResult func setPositionMode(mode: NMFMyPositionMode) -> Self { map.mapView.positionMode = mode + setLocationOverlay() return self } @@ -301,6 +304,11 @@ extension RNMapView { pathOverlay.outlineWidth = 0 pathOverlay.color = .m1 } + + private func setLocationOverlay() { + let locationOverlay = map.mapView.locationOverlay + locationOverlay.icon = locationOverlayIcon + } } // MARK: - UI & Layout @@ -351,6 +359,13 @@ extension RNMapView: NMFMapViewCameraDelegate, NMFMapViewTouchDelegate { guard isDrawMode && markers.count < 19 else { return } self.makeMarker(at: latlng) } + + func mapView(_ mapView: NMFMapView, cameraDidChangeByReason reason: Int, animated: Bool) { + let locationOverlay = map.mapView.locationOverlay + if locationOverlay.icon != locationOverlayIcon { + setLocationOverlay() + } + } } extension RNMapView: CLLocationManagerDelegate {} diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift index 5bcbfbc3..8d8e08f7 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift @@ -99,6 +99,7 @@ final class CourseDrawingVC: UIViewController { self.setLayout() self.setAddTarget() self.bindMapView() + self.setNavigationGesture(false) } } @@ -108,6 +109,7 @@ extension CourseDrawingVC { private func setAddTarget() { self.decideDepartureButton.addTarget(self, action: #selector(decideDepartureButtonDidTap), for: .touchUpInside) self.undoButton.addTarget(self, action: #selector(undoButtonDidTap), for: .touchUpInside) + self.completeButton.addTarget(self, action: #selector(completeButtonDidTap), for: .touchUpInside) } private func bindMapView() { @@ -121,6 +123,10 @@ extension CourseDrawingVC { self?.undoButton.isEnabled = (count >= 2) }.store(in: cancelBag) } + + private func setNavigationGesture(_ enabled: Bool) { + navigationController?.interactivePopGestureRecognizer?.isEnabled = enabled + } } // MARK: - @objc Function @@ -141,6 +147,27 @@ extension CourseDrawingVC { @objc private func undoButtonDidTap() { mapView.undo() } + + @objc private func completeButtonDidTap() { + let alertVC = CustomAlertVC() + alertVC.modalPresentationStyle = .overFullScreen + + alertVC.leftButtonTapped.sink { [weak self] _ in + guard let self = self else { return } + self.tabBarController?.selectedIndex = 1 + self.navigationController?.popToRootViewController(animated: true) + alertVC.dismiss(animated: true) + }.store(in: cancelBag) + + alertVC.rightButtonTapped.sink { [weak self] _ in + guard let self = self else { return } + let countDownVC = CountDownVC() + self.navigationController?.pushViewController(countDownVC, animated: true) + alertVC.dismiss(animated: true) + }.store(in: cancelBag) + + self.present(alertVC, animated: false) + } } // MARK: - UI & Layout diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/DepartureSearchVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/DepartureSearchVC.swift index 29183b24..9e6f1ec6 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/DepartureSearchVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/DepartureSearchVC.swift @@ -14,7 +14,7 @@ final class DepartureSearchVC: UIViewController { private lazy var naviBar = CustomNavigationBar(self, type: .search).setTextFieldPlaceholder(placeholder: "지역과 키워드 위주로 검색해보세요") private let dividerView = UIView().then { - $0.backgroundColor = .g4 + $0.backgroundColor = .g5 } private let locationTableView = UITableView(frame: .zero, style: .plain).then {