From c984f4ae8d792b6180c470a928e340c95b76bbe0 Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Tue, 3 Jan 2023 16:29:46 +0900 Subject: [PATCH 01/13] =?UTF-8?q?[Feat]=20#24=20-=20=EC=A7=80=EB=8F=84=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UIComponents/MapView/RNMapView.swift | 20 +++++++++++-- .../UIComponents/MapView/RNStartMarker.swift | 2 +- .../CourseDrawing/VC/CourseDrawingVC.swift | 29 +++++++++++++++++++ 3 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift diff --git a/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift b/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift index b65e8360..14ac5de5 100644 --- a/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift +++ b/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift @@ -89,19 +89,23 @@ extension RNMapView { /// 지정 위치에 startMarker와 출발 infoWindow 생성 (기존의 startMarker는 제거) @discardableResult - func makeStartMarker(at location: NMGLatLng) -> Self { + func makeStartMarker(at location: NMGLatLng, withCameraMove: Bool = false) -> Self { self.startMarker.position = location self.startMarker.mapView = self.map.mapView self.startMarker.showInfoWindow() + if withCameraMove { + moveToLocation(location: location) + } return self } /// 사용자 위치에 startMarker와 출발 infoWindow 생성 (기존의 startMarker는 제거) @discardableResult - func makeStartMarkerAtUserLocation() -> Self { + func makeStartMarkerAtUserLocation(withCameraMove: Bool = false) -> Self { self.startMarker.position = getUserLocation() self.startMarker.mapView = self.map.mapView self.startMarker.showInfoWindow() + moveToUserLocation() return self } @@ -149,6 +153,18 @@ extension RNMapView { return self } + /// 지정 위치로 카메라 이동 + @discardableResult + func moveToLocation(location: NMGLatLng) -> Self { + let cameraUpdate = NMFCameraUpdate(scrollTo: location) + + DispatchQueue.main.async { [self] in + cameraUpdate.animation = .easeIn + self.map.mapView.moveCamera(cameraUpdate) + } + return self + } + /// 저장된 위치들로 경로선 그리기 @discardableResult func makePath() -> Self { diff --git a/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNStartMarker.swift b/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNStartMarker.swift index a54503a9..be891500 100644 --- a/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNStartMarker.swift +++ b/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNStartMarker.swift @@ -60,7 +60,7 @@ extension RNStartMarker: NMFOverlayImageDataSource { func view(with overlay: NMFOverlay) -> UIView { // 마커 위에 보여줄 InfoView 이미지 리턴 let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 58, height: 34)) - imageView.image = ImageLiterals.icMapDeparture + imageView.image = ImageLiterals.icMapStart return imageView } } diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift new file mode 100644 index 00000000..4c461a2d --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift @@ -0,0 +1,29 @@ +// +// CourseDrawingVC.swift +// Runnect-iOS +// +// Created by sejin on 2023/01/03. +// + +import UIKit + +class CourseDrawingVC: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + + // Do any additional setup after loading the view. + } + + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destination. + // Pass the selected object to the new view controller. + } + */ + +} From 9558d09f21e8ad88081a78e2951e3d6af1c429f0 Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Tue, 3 Jan 2023 16:30:27 +0900 Subject: [PATCH 02/13] =?UTF-8?q?[Feat]=20#24=20-=20CustomNavigationBar?= =?UTF-8?q?=EC=97=90=20=EB=A9=94=EC=86=8C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Global/UIComponents/CustomNavigationBar.swift | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Runnect-iOS/Runnect-iOS/Global/UIComponents/CustomNavigationBar.swift b/Runnect-iOS/Runnect-iOS/Global/UIComponents/CustomNavigationBar.swift index 69fcdc0c..182df0c6 100644 --- a/Runnect-iOS/Runnect-iOS/Global/UIComponents/CustomNavigationBar.swift +++ b/Runnect-iOS/Runnect-iOS/Global/UIComponents/CustomNavigationBar.swift @@ -107,11 +107,24 @@ extension CustomNavigationBar { return self } + @discardableResult + func setTextFieldText(text: String) -> Self { + self.textField.text = text + self.textField.isUserInteractionEnabled = false + return self + } + @discardableResult func showKeyboard() -> Self { self.textField.becomeFirstResponder() return self } + + @discardableResult + func hideRightButton() -> Self { + self.rightButton.isHidden = true + return self + } } // MARK: - @objc Function From f1fd9085da0641d6184975430e3986a0830ac939 Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Tue, 3 Jan 2023 16:30:43 +0900 Subject: [PATCH 03/13] =?UTF-8?q?[Feat]=20#24=20-=20DepartureSearchVC=20?= =?UTF-8?q?=EA=B8=B0=EC=B4=88=20UI=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Runnect-iOS.xcodeproj/project.pbxproj | 4 + .../CourseDrawing/VC/CourseDrawingVC.swift | 107 ++++++++++++++++-- .../CourseDrawing/VC/DepartureSearchVC.swift | 6 + 3 files changed, 105 insertions(+), 12 deletions(-) diff --git a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj index b5e17360..bd3c1d1c 100644 --- a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj +++ b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj @@ -19,6 +19,7 @@ CE17F0352961BEF800E1DED0 /* Pretendard-SemiBold.otf in Resources */ = {isa = PBXBuildFile; fileRef = CE17F0312961BEF800E1DED0 /* Pretendard-SemiBold.otf */; }; CE17F0362961BEF800E1DED0 /* Pretendard-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = CE17F0322961BEF800E1DED0 /* Pretendard-Regular.otf */; }; CE17F0382961BF8B00E1DED0 /* FontLiterals.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE17F0372961BF8B00E1DED0 /* FontLiterals.swift */; }; + CE29D582296402B500F47542 /* CourseDrawingVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE29D581296402B500F47542 /* CourseDrawingVC.swift */; }; CE4545C9295D7AF4003201E1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4545C8295D7AF4003201E1 /* AppDelegate.swift */; }; CE4545CB295D7AF4003201E1 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4545CA295D7AF4003201E1 /* SceneDelegate.swift */; }; CE4545CD295D7AF4003201E1 /* TaBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4545CC295D7AF4003201E1 /* TaBarController.swift */; }; @@ -98,6 +99,7 @@ CE17F0312961BEF800E1DED0 /* Pretendard-SemiBold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Pretendard-SemiBold.otf"; sourceTree = ""; }; CE17F0322961BEF800E1DED0 /* Pretendard-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Pretendard-Regular.otf"; sourceTree = ""; }; CE17F0372961BF8B00E1DED0 /* FontLiterals.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontLiterals.swift; sourceTree = ""; }; + CE29D581296402B500F47542 /* CourseDrawingVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CourseDrawingVC.swift; sourceTree = ""; }; CE4545C5295D7AF4003201E1 /* Runnect-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Runnect-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; CE4545C8295D7AF4003201E1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; CE4545CA295D7AF4003201E1 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -295,6 +297,7 @@ CEEC6B392961C4F300D00E1E /* CourseDrawingHomeVC.swift */, CEC2A6912962BE2900160BF7 /* DepartureSearchVC.swift */, CEB8416F2963360800BF8080 /* CountDownVC.swift */, + CE29D581296402B500F47542 /* CourseDrawingVC.swift */, ); path = VC; sourceTree = ""; @@ -807,6 +810,7 @@ CE6655F4295D898400C64E12 /* UIViewController+.swift in Sources */, CE5645162961B72E000A2856 /* ImageLiterals.swift in Sources */, CE6655CD295D856300C64E12 /* KeyPathFindable.swift in Sources */, + CE29D582296402B500F47542 /* CourseDrawingVC.swift in Sources */, CE6655E4295D884600C64E12 /* UILabel+.swift in Sources */, CE6655FA295D90E000C64E12 /* applyShadow.swift in Sources */, A3BC2F2B2962C3D500198261 /* GoalRewardInfoVC.swift in Sources */, diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift index 4c461a2d..7bd8dc9e 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift @@ -7,23 +7,106 @@ import UIKit -class CourseDrawingVC: UIViewController { - +final class CourseDrawingVC: UIViewController { + + // MARK: - UI Components + + private let notchCoverView = UIView().then { + $0.backgroundColor = .w1 + } + private lazy var naviBar = CustomNavigationBar(self, type: .search) + .setTextFieldText(text: "검색 결과") + .hideRightButton() + + private let mapView = RNMapView().makeStartMarkerAtUserLocation() + + private let departureLocationLabel = UILabel().then { + $0.font = .b1 + $0.textColor = .g1 + $0.numberOfLines = 1 + $0.textAlignment = .left + $0.text = "장소 이름" + } + + private let departureDetailLocationLabel = UILabel().then { + $0.font = .b6 + $0.textColor = .g2 + $0.numberOfLines = 1 + $0.textAlignment = .left + $0.text = "상세 주소" + } + + private let decideDepartureButton = CustomButton(title: "출발지 설정하기") + + private let departureInfoContainerView = UIView().then { + $0.backgroundColor = .w1 + $0.layer.cornerRadius = 20 + $0.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] + } + + // MARK: - View Life Cycle + override func viewDidLoad() { super.viewDidLoad() - - // Do any additional setup after loading the view. + self.setUI() + self.setLayout() } +} + +// MARK: - Methods + +extension CourseDrawingVC { +} - /* - // MARK: - Navigation +// MARK: - UI & Layout - // In a storyboard-based application, you will often want to do a little preparation before navigation - override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - // Get the new view controller using segue.destination. - // Pass the selected object to the new view controller. +extension CourseDrawingVC { + private func setUI() { + self.view.backgroundColor = .w1 + self.departureInfoContainerView.layer.applyShadow(alpha: 0.35, x: 0, y: 3, blur: 10) + } + + private func setLayout() { + self.view.addSubviews(notchCoverView, naviBar, mapView, departureInfoContainerView) + self.departureInfoContainerView.addSubviews(departureLocationLabel, departureDetailLocationLabel, decideDepartureButton) + + view.bringSubviewToFront(notchCoverView) + view.bringSubviewToFront(naviBar) + + notchCoverView.snp.makeConstraints { make in + make.leading.top.trailing.equalToSuperview() + make.height.equalTo(-calculateTopInset()) + } + + naviBar.snp.makeConstraints { make in + make.leading.top.trailing.equalTo(view.safeAreaLayoutGuide) + make.height.equalTo(48) + } + + mapView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + + departureInfoContainerView.snp.makeConstraints { make in + make.leading.bottom.trailing.equalToSuperview() + make.height.equalTo(172) + } + + departureLocationLabel.snp.makeConstraints { make in + make.top.equalToSuperview().inset(28) + make.leading.trailing.equalToSuperview().inset(16) + } + + departureDetailLocationLabel.snp.makeConstraints { make in + make.top.equalTo(departureLocationLabel.snp.bottom).offset(6) + make.leading.trailing.equalToSuperview().inset(16) + } + + decideDepartureButton.snp.makeConstraints { make in + make.top.equalTo(departureDetailLocationLabel.snp.bottom).offset(24) + make.leading.trailing.equalToSuperview().inset(16) + make.height.equalTo(44) + } } - */ - } diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/DepartureSearchVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/DepartureSearchVC.swift index a037957e..29183b24 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/DepartureSearchVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/DepartureSearchVC.swift @@ -119,6 +119,12 @@ extension DepartureSearchVC: UITableViewDelegate, UITableViewDataSource { func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 68 } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + let courseDrawingVC = CourseDrawingVC() + courseDrawingVC.hidesBottomBarWhenPushed = true + self.navigationController?.pushViewController(courseDrawingVC, animated: true) + } } // MARK: - CustomNavigationBarDelegate From 62bbaa816d64fa24fe9c40a2b321ef385c55d85e Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Tue, 3 Jan 2023 17:04:27 +0900 Subject: [PATCH 04/13] =?UTF-8?q?[Feat]=20#21-=20=EC=B6=9C=EB=B0=9C?= =?UTF-8?q?=EC=A7=80=20=EC=84=A4=EC=A0=95=ED=95=98=EA=B8=B0=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=ED=81=B4=EB=A6=AD=20=EC=8B=9C=20=EC=95=A0=EB=8B=88?= =?UTF-8?q?=EB=A9=94=EC=9D=B4=EC=85=98=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Runnect-iOS.xcodeproj/project.pbxproj | 4 ++ .../Utils/caculateStatusBarHeight.swift | 25 +++++++++++ .../CourseDrawing/VC/CourseDrawingVC.swift | 41 +++++++++++++++---- 3 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 Runnect-iOS/Runnect-iOS/Global/Utils/caculateStatusBarHeight.swift diff --git a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj index bd3c1d1c..f762a255 100644 --- a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj +++ b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj @@ -20,6 +20,7 @@ CE17F0362961BEF800E1DED0 /* Pretendard-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = CE17F0322961BEF800E1DED0 /* Pretendard-Regular.otf */; }; CE17F0382961BF8B00E1DED0 /* FontLiterals.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE17F0372961BF8B00E1DED0 /* FontLiterals.swift */; }; CE29D582296402B500F47542 /* CourseDrawingVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE29D581296402B500F47542 /* CourseDrawingVC.swift */; }; + CE29D584296416D800F47542 /* caculateStatusBarHeight.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE29D583296416D800F47542 /* caculateStatusBarHeight.swift */; }; CE4545C9295D7AF4003201E1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4545C8295D7AF4003201E1 /* AppDelegate.swift */; }; CE4545CB295D7AF4003201E1 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4545CA295D7AF4003201E1 /* SceneDelegate.swift */; }; CE4545CD295D7AF4003201E1 /* TaBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE4545CC295D7AF4003201E1 /* TaBarController.swift */; }; @@ -100,6 +101,7 @@ CE17F0322961BEF800E1DED0 /* Pretendard-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Pretendard-Regular.otf"; sourceTree = ""; }; CE17F0372961BF8B00E1DED0 /* FontLiterals.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontLiterals.swift; sourceTree = ""; }; CE29D581296402B500F47542 /* CourseDrawingVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CourseDrawingVC.swift; sourceTree = ""; }; + CE29D583296416D800F47542 /* caculateStatusBarHeight.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = caculateStatusBarHeight.swift; sourceTree = ""; }; CE4545C5295D7AF4003201E1 /* Runnect-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Runnect-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; CE4545C8295D7AF4003201E1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; CE4545CA295D7AF4003201E1 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -516,6 +518,7 @@ CE58759F29601500005D967E /* Toast.swift */, CE6655C9295D84DD00C64E12 /* UserDefaultKeyList.swift */, CEC2A68F2962B06C00160BF7 /* convertLocationObject.swift */, + CE29D583296416D800F47542 /* caculateStatusBarHeight.swift */, ); path = Utils; sourceTree = ""; @@ -845,6 +848,7 @@ CEEC6B3A2961C4F300D00E1E /* CourseDrawingHomeVC.swift in Sources */, CEC2A6902962B06C00160BF7 /* convertLocationObject.swift in Sources */, CEC2A6852961F92C00160BF7 /* CustomButton.swift in Sources */, + CE29D584296416D800F47542 /* caculateStatusBarHeight.swift in Sources */, CE66560C295D928300C64E12 /* setRootViewController.swift in Sources */, CE6655D9295D871B00C64E12 /* URL+.swift in Sources */, CE6655DE295D877F00C64E12 /* UIColor+.swift in Sources */, diff --git a/Runnect-iOS/Runnect-iOS/Global/Utils/caculateStatusBarHeight.swift b/Runnect-iOS/Runnect-iOS/Global/Utils/caculateStatusBarHeight.swift new file mode 100644 index 00000000..5ef16c8e --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Utils/caculateStatusBarHeight.swift @@ -0,0 +1,25 @@ +// +// caculateStatusBarHeight.swift +// Runnect-iOS +// +// Created by sejin on 2023/01/03. +// + +import UIKit + +extension UIApplication { + var statusBarHeight: CGFloat { + connectedScenes + .compactMap { + $0 as? UIWindowScene + } + .compactMap { + $0.statusBarManager + } + .map { + $0.statusBarFrame + } + .map(\.height) + .max() ?? 0 + } +} diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift index 7bd8dc9e..69fe1237 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift @@ -18,6 +18,12 @@ final class CourseDrawingVC: UIViewController { .setTextFieldText(text: "검색 결과") .hideRightButton() + private lazy var naviBarContainerStackView = UIStackView( + arrangedSubviews: [notchCoverView, naviBar] + ).then { + $0.axis = .vertical + } + private let mapView = RNMapView().makeStartMarkerAtUserLocation() private let departureLocationLabel = UILabel().then { @@ -50,13 +56,28 @@ final class CourseDrawingVC: UIViewController { super.viewDidLoad() self.setUI() self.setLayout() + self.setAddTarget() } } // MARK: - Methods extension CourseDrawingVC { - + private func setAddTarget() { + self.decideDepartureButton.addTarget(self, action: #selector(decideDepartureButtonDidTap), for: .touchUpInside) + } +} + +// MARK: - @objc Function + +extension CourseDrawingVC { + @objc private func decideDepartureButtonDidTap() { + UIView.animate(withDuration: 1.0) { + let naviBarContainerStackViewHeight = self.naviBarContainerStackView.frame.height + self.naviBarContainerStackView.transform = CGAffineTransform(translationX: 0, y: -naviBarContainerStackViewHeight) + self.departureInfoContainerView.transform = CGAffineTransform(translationX: 0, y: 172) + } + } } // MARK: - UI & Layout @@ -68,22 +89,28 @@ extension CourseDrawingVC { } private func setLayout() { - self.view.addSubviews(notchCoverView, naviBar, mapView, departureInfoContainerView) + self.view.addSubviews(naviBarContainerStackView, mapView, departureInfoContainerView) self.departureInfoContainerView.addSubviews(departureLocationLabel, departureDetailLocationLabel, decideDepartureButton) - view.bringSubviewToFront(notchCoverView) - view.bringSubviewToFront(naviBar) + view.bringSubviewToFront(naviBarContainerStackView) notchCoverView.snp.makeConstraints { make in - make.leading.top.trailing.equalToSuperview() - make.height.equalTo(-calculateTopInset()) + var notchHeight = calculateTopInset() + if notchHeight == -44 { + let statusBarHeight = UIApplication.shared.statusBarHeight + notchHeight = -statusBarHeight + } + make.height.equalTo(-notchHeight) } naviBar.snp.makeConstraints { make in - make.leading.top.trailing.equalTo(view.safeAreaLayoutGuide) make.height.equalTo(48) } + naviBarContainerStackView.snp.makeConstraints { make in + make.leading.top.trailing.equalToSuperview() + } + mapView.snp.makeConstraints { make in make.edges.equalToSuperview() } From 8a5fa1473e7b0f95b94bc0a7c5a685a1670aa30a Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Tue, 3 Jan 2023 17:13:22 +0900 Subject: [PATCH 05/13] =?UTF-8?q?[Feat]=20#21=20-=20=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=EC=A0=84=ED=99=98=20=EC=8B=9C=20=EB=84=A4=EB=B9=84=EB=B0=94=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CourseDrawing/VC/CourseDrawingVC.swift | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift index 69fe1237..b9201ddb 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift @@ -18,6 +18,11 @@ final class CourseDrawingVC: UIViewController { .setTextFieldText(text: "검색 결과") .hideRightButton() + private lazy var naviBarForEditing = CustomNavigationBar(self, type: .titleWithLeftButton) + .then { + $0.alpha = 0 + } + private lazy var naviBarContainerStackView = UIStackView( arrangedSubviews: [notchCoverView, naviBar] ).then { @@ -72,6 +77,8 @@ extension CourseDrawingVC { extension CourseDrawingVC { @objc private func decideDepartureButtonDidTap() { + + showHiddenViews() UIView.animate(withDuration: 1.0) { let naviBarContainerStackViewHeight = self.naviBarContainerStackView.frame.height self.naviBarContainerStackView.transform = CGAffineTransform(translationX: 0, y: -naviBarContainerStackViewHeight) @@ -86,12 +93,13 @@ extension CourseDrawingVC { private func setUI() { self.view.backgroundColor = .w1 self.departureInfoContainerView.layer.applyShadow(alpha: 0.35, x: 0, y: 3, blur: 10) + self.naviBarForEditing.backgroundColor = .clear } private func setLayout() { self.view.addSubviews(naviBarContainerStackView, mapView, departureInfoContainerView) self.departureInfoContainerView.addSubviews(departureLocationLabel, departureDetailLocationLabel, decideDepartureButton) - + setHiddenViewsLayout() view.bringSubviewToFront(naviBarContainerStackView) notchCoverView.snp.makeConstraints { make in @@ -119,7 +127,7 @@ extension CourseDrawingVC { make.leading.bottom.trailing.equalToSuperview() make.height.equalTo(172) } - + departureLocationLabel.snp.makeConstraints { make in make.top.equalToSuperview().inset(28) make.leading.trailing.equalToSuperview().inset(16) @@ -136,4 +144,20 @@ extension CourseDrawingVC { make.height.equalTo(44) } } + + private func setHiddenViewsLayout() { + view.addSubviews(naviBarForEditing) + view.sendSubviewToBack(naviBarForEditing) + naviBarForEditing.snp.makeConstraints { make in + make.leading.top.trailing.equalTo(view.safeAreaLayoutGuide) + make.height.equalTo(48) + } + } + + private func showHiddenViews() { + view.bringSubviewToFront(naviBarForEditing) + UIView.animate(withDuration: 1.0) { + self.naviBarForEditing.alpha = 1 + } + } } From 74c69eaffe108e65c31c7c79e0ec09ba842a1c04 Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Tue, 3 Jan 2023 17:55:58 +0900 Subject: [PATCH 06/13] =?UTF-8?q?[Feat]=20#24=20-=20mapView=EC=9D=98=20unD?= =?UTF-8?q?o=20=EB=B2=84=ED=8A=BC=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UIComponents/MapView/RNMapView.swift | 10 +++- .../CourseDrawing/VC/CourseDrawingVC.swift | 58 ++++++++++++++++--- 2 files changed, 59 insertions(+), 9 deletions(-) diff --git a/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift b/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift index 14ac5de5..6a5fb5b1 100644 --- a/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift +++ b/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift @@ -188,6 +188,12 @@ extension RNMapView { @discardableResult func showUndoButton(toShow: Bool) -> Self { self.undoButton.isHidden = !toShow + if toShow { + UIView.animate(withDuration: 0.7) { + self.undoButton.transform = CGAffineTransform(translationX: 0, y: -(self.undoButton.frame.height + 100)) + } + } + setUndoButton() return self } @@ -331,8 +337,8 @@ extension RNMapView { } undoButton.snp.makeConstraints { make in - make.bottom.equalToSuperview().inset(98+bottomPadding) - make.trailing.equalToSuperview().inset(24) + make.top.equalTo(self.snp.bottom) + make.trailing.equalToSuperview().inset(16) } } diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift index b9201ddb..c905a4f0 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift @@ -55,6 +55,30 @@ final class CourseDrawingVC: UIViewController { $0.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] } + private let distanceLabel = UILabel().then { + $0.font = .h1 + $0.textColor = .g1 + $0.text = "0.0" + } + + private let kilometerLabel = UILabel().then { + $0.font = .b4 + $0.textColor = .g2 + $0.text = "km" + } + + private lazy var distanceStackView = UIStackView( + arrangedSubviews: [distanceLabel, kilometerLabel] + ).then { + $0.spacing = 3 + $0.alignment = .bottom + } + + private let distanceContainerView = UIView().then { + $0.backgroundColor = .w1 + $0.layer.cornerRadius = 22 + } + // MARK: - View Life Cycle override func viewDidLoad() { @@ -77,9 +101,11 @@ extension CourseDrawingVC { extension CourseDrawingVC { @objc private func decideDepartureButtonDidTap() { - showHiddenViews() - UIView.animate(withDuration: 1.0) { + + mapView.showUndoButton(toShow: true) + + UIView.animate(withDuration: 0.7) { let naviBarContainerStackViewHeight = self.naviBarContainerStackView.frame.height self.naviBarContainerStackView.transform = CGAffineTransform(translationX: 0, y: -naviBarContainerStackViewHeight) self.departureInfoContainerView.transform = CGAffineTransform(translationX: 0, y: 172) @@ -92,14 +118,15 @@ extension CourseDrawingVC { extension CourseDrawingVC { private func setUI() { self.view.backgroundColor = .w1 - self.departureInfoContainerView.layer.applyShadow(alpha: 0.35, x: 0, y: 3, blur: 10) self.naviBarForEditing.backgroundColor = .clear + self.departureInfoContainerView.layer.applyShadow(alpha: 0.35, x: 0, y: 3, blur: 10) + self.distanceContainerView.layer.applyShadow(alpha: 0.2, x: 2, y: 4, blur: 9) } private func setLayout() { + setHiddenViewsLayout() self.view.addSubviews(naviBarContainerStackView, mapView, departureInfoContainerView) self.departureInfoContainerView.addSubviews(departureLocationLabel, departureDetailLocationLabel, decideDepartureButton) - setHiddenViewsLayout() view.bringSubviewToFront(naviBarContainerStackView) notchCoverView.snp.makeConstraints { make in @@ -146,18 +173,35 @@ extension CourseDrawingVC { } private func setHiddenViewsLayout() { - view.addSubviews(naviBarForEditing) + view.addSubviews(naviBarForEditing, distanceContainerView) view.sendSubviewToBack(naviBarForEditing) naviBarForEditing.snp.makeConstraints { make in make.leading.top.trailing.equalTo(view.safeAreaLayoutGuide) make.height.equalTo(48) } + + distanceContainerView.snp.makeConstraints { make in + make.width.equalTo(96) + make.height.equalTo(44) + make.leading.equalTo(view.safeAreaLayoutGuide).inset(16) + make.top.equalTo(view.snp.bottom) + } + + distanceContainerView.addSubviews(distanceStackView) + + distanceStackView.snp.makeConstraints { make in + make.center.equalToSuperview() + } } private func showHiddenViews() { - view.bringSubviewToFront(naviBarForEditing) - UIView.animate(withDuration: 1.0) { + [naviBarForEditing, distanceContainerView].forEach { subView in + view.bringSubviewToFront(subView) + } + + UIView.animate(withDuration: 0.7) { self.naviBarForEditing.alpha = 1 + self.distanceContainerView.transform = CGAffineTransform(translationX: 0, y: -151) } } } From 482953e2e3720d3c031c3a5ba4a4cda5bd25a272 Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Tue, 3 Jan 2023 17:13:22 +0900 Subject: [PATCH 07/13] =?UTF-8?q?[Feat]=20#24=20-=20=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=EC=A0=84=ED=99=98=20=EC=8B=9C=20=EB=84=A4=EB=B9=84=EB=B0=94=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CourseDrawing/VC/CourseDrawingVC.swift | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift index 69fe1237..b9201ddb 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift @@ -18,6 +18,11 @@ final class CourseDrawingVC: UIViewController { .setTextFieldText(text: "검색 결과") .hideRightButton() + private lazy var naviBarForEditing = CustomNavigationBar(self, type: .titleWithLeftButton) + .then { + $0.alpha = 0 + } + private lazy var naviBarContainerStackView = UIStackView( arrangedSubviews: [notchCoverView, naviBar] ).then { @@ -72,6 +77,8 @@ extension CourseDrawingVC { extension CourseDrawingVC { @objc private func decideDepartureButtonDidTap() { + + showHiddenViews() UIView.animate(withDuration: 1.0) { let naviBarContainerStackViewHeight = self.naviBarContainerStackView.frame.height self.naviBarContainerStackView.transform = CGAffineTransform(translationX: 0, y: -naviBarContainerStackViewHeight) @@ -86,12 +93,13 @@ extension CourseDrawingVC { private func setUI() { self.view.backgroundColor = .w1 self.departureInfoContainerView.layer.applyShadow(alpha: 0.35, x: 0, y: 3, blur: 10) + self.naviBarForEditing.backgroundColor = .clear } private func setLayout() { self.view.addSubviews(naviBarContainerStackView, mapView, departureInfoContainerView) self.departureInfoContainerView.addSubviews(departureLocationLabel, departureDetailLocationLabel, decideDepartureButton) - + setHiddenViewsLayout() view.bringSubviewToFront(naviBarContainerStackView) notchCoverView.snp.makeConstraints { make in @@ -119,7 +127,7 @@ extension CourseDrawingVC { make.leading.bottom.trailing.equalToSuperview() make.height.equalTo(172) } - + departureLocationLabel.snp.makeConstraints { make in make.top.equalToSuperview().inset(28) make.leading.trailing.equalToSuperview().inset(16) @@ -136,4 +144,20 @@ extension CourseDrawingVC { make.height.equalTo(44) } } + + private func setHiddenViewsLayout() { + view.addSubviews(naviBarForEditing) + view.sendSubviewToBack(naviBarForEditing) + naviBarForEditing.snp.makeConstraints { make in + make.leading.top.trailing.equalTo(view.safeAreaLayoutGuide) + make.height.equalTo(48) + } + } + + private func showHiddenViews() { + view.bringSubviewToFront(naviBarForEditing) + UIView.animate(withDuration: 1.0) { + self.naviBarForEditing.alpha = 1 + } + } } From 6f250913ebf383a74e60d2bba97eab261a19dc66 Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Tue, 3 Jan 2023 17:55:58 +0900 Subject: [PATCH 08/13] =?UTF-8?q?[Feat]=20#24=20-=20mapView=EC=9D=98=20unD?= =?UTF-8?q?o=20=EB=B2=84=ED=8A=BC=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UIComponents/MapView/RNMapView.swift | 10 +++- .../CourseDrawing/VC/CourseDrawingVC.swift | 58 ++++++++++++++++--- 2 files changed, 59 insertions(+), 9 deletions(-) diff --git a/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift b/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift index 14ac5de5..6a5fb5b1 100644 --- a/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift +++ b/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift @@ -188,6 +188,12 @@ extension RNMapView { @discardableResult func showUndoButton(toShow: Bool) -> Self { self.undoButton.isHidden = !toShow + if toShow { + UIView.animate(withDuration: 0.7) { + self.undoButton.transform = CGAffineTransform(translationX: 0, y: -(self.undoButton.frame.height + 100)) + } + } + setUndoButton() return self } @@ -331,8 +337,8 @@ extension RNMapView { } undoButton.snp.makeConstraints { make in - make.bottom.equalToSuperview().inset(98+bottomPadding) - make.trailing.equalToSuperview().inset(24) + make.top.equalTo(self.snp.bottom) + make.trailing.equalToSuperview().inset(16) } } diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift index b9201ddb..c905a4f0 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift @@ -55,6 +55,30 @@ final class CourseDrawingVC: UIViewController { $0.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] } + private let distanceLabel = UILabel().then { + $0.font = .h1 + $0.textColor = .g1 + $0.text = "0.0" + } + + private let kilometerLabel = UILabel().then { + $0.font = .b4 + $0.textColor = .g2 + $0.text = "km" + } + + private lazy var distanceStackView = UIStackView( + arrangedSubviews: [distanceLabel, kilometerLabel] + ).then { + $0.spacing = 3 + $0.alignment = .bottom + } + + private let distanceContainerView = UIView().then { + $0.backgroundColor = .w1 + $0.layer.cornerRadius = 22 + } + // MARK: - View Life Cycle override func viewDidLoad() { @@ -77,9 +101,11 @@ extension CourseDrawingVC { extension CourseDrawingVC { @objc private func decideDepartureButtonDidTap() { - showHiddenViews() - UIView.animate(withDuration: 1.0) { + + mapView.showUndoButton(toShow: true) + + UIView.animate(withDuration: 0.7) { let naviBarContainerStackViewHeight = self.naviBarContainerStackView.frame.height self.naviBarContainerStackView.transform = CGAffineTransform(translationX: 0, y: -naviBarContainerStackViewHeight) self.departureInfoContainerView.transform = CGAffineTransform(translationX: 0, y: 172) @@ -92,14 +118,15 @@ extension CourseDrawingVC { extension CourseDrawingVC { private func setUI() { self.view.backgroundColor = .w1 - self.departureInfoContainerView.layer.applyShadow(alpha: 0.35, x: 0, y: 3, blur: 10) self.naviBarForEditing.backgroundColor = .clear + self.departureInfoContainerView.layer.applyShadow(alpha: 0.35, x: 0, y: 3, blur: 10) + self.distanceContainerView.layer.applyShadow(alpha: 0.2, x: 2, y: 4, blur: 9) } private func setLayout() { + setHiddenViewsLayout() self.view.addSubviews(naviBarContainerStackView, mapView, departureInfoContainerView) self.departureInfoContainerView.addSubviews(departureLocationLabel, departureDetailLocationLabel, decideDepartureButton) - setHiddenViewsLayout() view.bringSubviewToFront(naviBarContainerStackView) notchCoverView.snp.makeConstraints { make in @@ -146,18 +173,35 @@ extension CourseDrawingVC { } private func setHiddenViewsLayout() { - view.addSubviews(naviBarForEditing) + view.addSubviews(naviBarForEditing, distanceContainerView) view.sendSubviewToBack(naviBarForEditing) naviBarForEditing.snp.makeConstraints { make in make.leading.top.trailing.equalTo(view.safeAreaLayoutGuide) make.height.equalTo(48) } + + distanceContainerView.snp.makeConstraints { make in + make.width.equalTo(96) + make.height.equalTo(44) + make.leading.equalTo(view.safeAreaLayoutGuide).inset(16) + make.top.equalTo(view.snp.bottom) + } + + distanceContainerView.addSubviews(distanceStackView) + + distanceStackView.snp.makeConstraints { make in + make.center.equalToSuperview() + } } private func showHiddenViews() { - view.bringSubviewToFront(naviBarForEditing) - UIView.animate(withDuration: 1.0) { + [naviBarForEditing, distanceContainerView].forEach { subView in + view.bringSubviewToFront(subView) + } + + UIView.animate(withDuration: 0.7) { self.naviBarForEditing.alpha = 1 + self.distanceContainerView.transform = CGAffineTransform(translationX: 0, y: -151) } } } From fae365c88416546adf536e1b0002e4ea5968260e Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Tue, 3 Jan 2023 18:27:36 +0900 Subject: [PATCH 09/13] [Feat] #24 - mapView Binding --- .../UIComponents/MapView/RNMapView.swift | 10 +++---- .../CourseDrawing/VC/CourseDrawingVC.swift | 27 +++++++++++++++++-- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift b/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift index 6a5fb5b1..8b99a25e 100644 --- a/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift +++ b/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift @@ -300,9 +300,9 @@ extension RNMapView { } private func setPathOverlay() { - pathOverlay.width = 3 + pathOverlay.width = 4 pathOverlay.outlineWidth = 0 - pathOverlay.color = .purple + pathOverlay.color = .m1 } private func setUndoButton() { @@ -335,10 +335,10 @@ extension RNMapView { make.bottom.equalToSuperview().inset(98+bottomPadding) make.trailing.equalToSuperview().inset(24) } - + undoButton.snp.makeConstraints { make in make.top.equalTo(self.snp.bottom) - make.trailing.equalToSuperview().inset(16) + make.trailing.equalToSuperview() } } @@ -370,7 +370,7 @@ extension RNMapView { extension RNMapView: NMFMapViewCameraDelegate, NMFMapViewTouchDelegate { // 지도 탭 이벤트 func mapView(_ mapView: NMFMapView, didTapMap latlng: NMGLatLng, point: CGPoint) { - guard isDrawMode else { return } + guard isDrawMode && markers.count < 19 else { return } self.makeMarker(at: latlng) } } diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift index c905a4f0..248b4705 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift @@ -6,9 +6,14 @@ // import UIKit +import Combine final class CourseDrawingVC: UIViewController { + // MARK: - Properties + + private var cancelBag = CancelBag() + // MARK: - UI Components private let notchCoverView = UIView().then { @@ -79,6 +84,8 @@ final class CourseDrawingVC: UIViewController { $0.layer.cornerRadius = 22 } + private let completeButton = CustomButton(title: "완성하기") + // MARK: - View Life Cycle override func viewDidLoad() { @@ -86,6 +93,7 @@ final class CourseDrawingVC: UIViewController { self.setUI() self.setLayout() self.setAddTarget() + self.bindMapView() } } @@ -95,6 +103,13 @@ extension CourseDrawingVC { private func setAddTarget() { self.decideDepartureButton.addTarget(self, action: #selector(decideDepartureButtonDidTap), for: .touchUpInside) } + + private func bindMapView() { + mapView.$pathDistance.sink { distance in + let kilometers = String(format: "%.1f", distance/1000) + self.distanceLabel.text = kilometers + }.store(in: cancelBag) + } } // MARK: - @objc Function @@ -104,6 +119,7 @@ extension CourseDrawingVC { showHiddenViews() mapView.showUndoButton(toShow: true) + mapView.setDrawMode(to: true) UIView.animate(withDuration: 0.7) { let naviBarContainerStackViewHeight = self.naviBarContainerStackView.frame.height @@ -173,7 +189,7 @@ extension CourseDrawingVC { } private func setHiddenViewsLayout() { - view.addSubviews(naviBarForEditing, distanceContainerView) + view.addSubviews(naviBarForEditing, distanceContainerView, completeButton) view.sendSubviewToBack(naviBarForEditing) naviBarForEditing.snp.makeConstraints { make in make.leading.top.trailing.equalTo(view.safeAreaLayoutGuide) @@ -192,16 +208,23 @@ extension CourseDrawingVC { distanceStackView.snp.makeConstraints { make in make.center.equalToSuperview() } + + completeButton.snp.makeConstraints { make in + make.leading.trailing.equalTo(view.safeAreaLayoutGuide).inset(16) + make.height.equalTo(44) + make.top.equalTo(view.snp.bottom).offset(34) + } } private func showHiddenViews() { - [naviBarForEditing, distanceContainerView].forEach { subView in + [naviBarForEditing, distanceContainerView, completeButton].forEach { subView in view.bringSubviewToFront(subView) } UIView.animate(withDuration: 0.7) { self.naviBarForEditing.alpha = 1 self.distanceContainerView.transform = CGAffineTransform(translationX: 0, y: -151) + self.completeButton.transform = CGAffineTransform(translationX: 0, y: -112) } } } From cdc1632a36427bebee73d55b1181c73a60edaf79 Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Tue, 3 Jan 2023 18:49:46 +0900 Subject: [PATCH 10/13] =?UTF-8?q?[Fix]=20#24=20-=20=EC=A7=80=EB=8F=84=20?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift | 6 +++--- .../Presentation/CourseDrawing/VC/CourseDrawingVC.swift | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift b/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift index 8b99a25e..9e842c9e 100644 --- a/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift +++ b/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift @@ -335,15 +335,15 @@ extension RNMapView { make.bottom.equalToSuperview().inset(98+bottomPadding) make.trailing.equalToSuperview().inset(24) } - + undoButton.snp.makeConstraints { make in - make.top.equalTo(self.snp.bottom) make.trailing.equalToSuperview() + make.top.equalTo(self.snp.bottom) } } private func updateSubviewsConstraints() { - [locationButton, undoButton].forEach { view in + [locationButton].forEach { view in view.snp.updateConstraints { make in make.bottom.equalToSuperview().inset(98+bottomPadding) } diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift index c05f57e7..aa3e6644 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift @@ -218,7 +218,7 @@ extension CourseDrawingVC { } private func showHiddenViews() { - [naviBarForEditing, distanceContainerView].forEach { subView in + [naviBarForEditing, distanceContainerView, completeButton].forEach { subView in view.bringSubviewToFront(subView) } From 9b46cb772ea88ea70900d09f95ba5a04e74f57ee Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Tue, 3 Jan 2023 18:55:06 +0900 Subject: [PATCH 11/13] =?UTF-8?q?[Feat]=20#24=20-=20marker=EA=B0=80=202?= =?UTF-8?q?=EA=B0=9C=20=EC=9D=B4=EC=83=81=EC=9D=BC=20=EB=95=8C=20=EC=99=84?= =?UTF-8?q?=EC=84=B1=ED=95=98=EA=B8=B0=20=EB=B2=84=ED=8A=BC=20enabled=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Global/UIComponents/MapView/RNMapView.swift | 5 +++++ .../Presentation/CourseDrawing/VC/CourseDrawingVC.swift | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift b/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift index 9e842c9e..f5a9f2a5 100644 --- a/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift +++ b/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift @@ -17,6 +17,8 @@ final class RNMapView: UIView { // MARK: - Properties @Published var pathDistance: Double = 0 + @Published var markerCount = 0 + let pathImage = PassthroughSubject() var cancelBag = Set() @@ -24,6 +26,7 @@ final class RNMapView: UIView { private var isDrawMode: Bool = false private var markers = [RNMarker]() { didSet { + markerCount = markers.count + 1 self.makePath() self.setUndoButton() } @@ -96,6 +99,7 @@ extension RNMapView { if withCameraMove { moveToLocation(location: location) } + markerCount = 1 return self } @@ -106,6 +110,7 @@ extension RNMapView { self.startMarker.mapView = self.map.mapView self.startMarker.showInfoWindow() moveToUserLocation() + markerCount = 1 return self } diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift index aa3e6644..944fa4cc 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift @@ -84,7 +84,7 @@ final class CourseDrawingVC: UIViewController { $0.layer.cornerRadius = 22 } - private let completeButton = CustomButton(title: "완성하기") + private let completeButton = CustomButton(title: "완성하기").setEnabled(false) // MARK: - View Life Cycle @@ -109,6 +109,11 @@ extension CourseDrawingVC { let kilometers = String(format: "%.1f", distance/1000) self.distanceLabel.text = kilometers }.store(in: cancelBag) + + mapView.$markerCount.sink { [weak self] count in + print(count) + self?.completeButton.setEnabled(count >= 2) + }.store(in: cancelBag) } } From a34536fb667b7a2f83fb2426fe5fb69dfb3b694d Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Tue, 3 Jan 2023 21:18:35 +0900 Subject: [PATCH 12/13] =?UTF-8?q?[Feat]=20#24=20-=20undoButton=EC=9D=98=20?= =?UTF-8?q?=EC=9C=84=EC=B9=98=EB=A5=BC=20RNMapView=EC=97=90=EC=84=9C=20VC?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UIComponents/MapView/RNMapView.swift | 45 ++++--------------- .../CourseDrawing/VC/CourseDrawingVC.swift | 25 ++++++++--- 2 files changed, 29 insertions(+), 41 deletions(-) diff --git a/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift b/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift index f5a9f2a5..d225a73f 100644 --- a/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift +++ b/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift @@ -28,7 +28,6 @@ final class RNMapView: UIView { didSet { markerCount = markers.count + 1 self.makePath() - self.setUndoButton() } } /// startMarker를 포함한 모든 마커들의 위치 정보 @@ -43,7 +42,6 @@ final class RNMapView: UIView { private var startMarker = RNStartMarker() private let pathOverlay = NMFPath() private let locationButton = UIButton(type: .custom) - private let undoButton = UIButton(type: .custom) // MARK: - initialization @@ -189,19 +187,6 @@ extension RNMapView { return self } - /// undoButton 설정 - @discardableResult - func showUndoButton(toShow: Bool) -> Self { - self.undoButton.isHidden = !toShow - if toShow { - UIView.animate(withDuration: 0.7) { - self.undoButton.transform = CGAffineTransform(translationX: 0, y: -(self.undoButton.frame.height + 100)) - } - } - setUndoButton() - return self - } - /// 지도에 ContentPadding을 지정하여 중심 위치가 변경되게 설정 @discardableResult func makeContentPadding(padding: UIEdgeInsets) -> Self { @@ -244,7 +229,7 @@ extension RNMapView { } } - // 바운더리(MBR) 생성 + /// 바운더리(MBR) 생성 func makeMBR() -> NMGLatLngBounds { var latitudes = [Double]() var longitudes = [Double]() @@ -258,6 +243,13 @@ extension RNMapView { return NMGLatLngBounds(southWest: southWest, northEast: northEast) } + /// 직전의 마커 생성을 취소하고 경로선도 제거 + func undo() { + guard let lastMarker = self.markers.popLast() else { return } + substractDistance(with: lastMarker.position) + lastMarker.mapView = nil + } + // 두 지점 사이의 거리(m) 추가 private func addDistance(with newLocation: NMGLatLng) { let lastCLLoc = markersLatLngs.last?.toCLLocation() @@ -309,10 +301,6 @@ extension RNMapView { pathOverlay.outlineWidth = 0 pathOverlay.color = .m1 } - - private func setUndoButton() { - self.undoButton.isEnabled = (markers.count >= 1) - } } // MARK: - UI & Layout @@ -323,14 +311,10 @@ extension RNMapView { self.locationButton.setImage(ImageLiterals.icMapLocation, for: .normal) self.locationButton.isHidden = true self.locationButton.addTarget(self, action: #selector(locationButtonDidTap), for: .touchUpInside) - - self.undoButton.setImage(ImageLiterals.icCancel, for: .normal) - self.undoButton.isHidden = true - self.undoButton.addTarget(self, action: #selector(undoButtonDidTap), for: .touchUpInside) } private func setLayout() { - addSubviews(map, locationButton, undoButton) + addSubviews(map, locationButton) map.snp.makeConstraints { make in make.edges.equalToSuperview() @@ -340,11 +324,6 @@ extension RNMapView { make.bottom.equalToSuperview().inset(98+bottomPadding) make.trailing.equalToSuperview().inset(24) } - - undoButton.snp.makeConstraints { make in - make.trailing.equalToSuperview() - make.top.equalTo(self.snp.bottom) - } } private func updateSubviewsConstraints() { @@ -362,12 +341,6 @@ extension RNMapView { @objc func locationButtonDidTap() { self.setPositionMode(mode: .direction) } - - @objc func undoButtonDidTap() { - guard let lastMarker = self.markers.popLast() else { return } - substractDistance(with: lastMarker.position) - lastMarker.mapView = nil - } } // MARK: - NMFMapViewCameraDelegate, NMFMapViewTouchDelegate diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift index 944fa4cc..5bcbfbc3 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift @@ -19,6 +19,7 @@ final class CourseDrawingVC: UIViewController { private let notchCoverView = UIView().then { $0.backgroundColor = .w1 } + private lazy var naviBar = CustomNavigationBar(self, type: .search) .setTextFieldText(text: "검색 결과") .hideRightButton() @@ -84,6 +85,10 @@ final class CourseDrawingVC: UIViewController { $0.layer.cornerRadius = 22 } + private let undoButton = UIButton(type: .custom).then { + $0.setImage(ImageLiterals.icCancel, for: .normal) + } + private let completeButton = CustomButton(title: "완성하기").setEnabled(false) // MARK: - View Life Cycle @@ -102,6 +107,7 @@ final class CourseDrawingVC: UIViewController { extension CourseDrawingVC { private func setAddTarget() { self.decideDepartureButton.addTarget(self, action: #selector(decideDepartureButtonDidTap), for: .touchUpInside) + self.undoButton.addTarget(self, action: #selector(undoButtonDidTap), for: .touchUpInside) } private func bindMapView() { @@ -111,8 +117,8 @@ extension CourseDrawingVC { }.store(in: cancelBag) mapView.$markerCount.sink { [weak self] count in - print(count) self?.completeButton.setEnabled(count >= 2) + self?.undoButton.isEnabled = (count >= 2) }.store(in: cancelBag) } } @@ -122,8 +128,7 @@ extension CourseDrawingVC { extension CourseDrawingVC { @objc private func decideDepartureButtonDidTap() { showHiddenViews() - - mapView.showUndoButton(toShow: true) + mapView.setDrawMode(to: true) UIView.animate(withDuration: 0.7) { @@ -132,6 +137,10 @@ extension CourseDrawingVC { self.departureInfoContainerView.transform = CGAffineTransform(translationX: 0, y: 172) } } + + @objc private func undoButtonDidTap() { + mapView.undo() + } } // MARK: - UI & Layout @@ -194,7 +203,7 @@ extension CourseDrawingVC { } private func setHiddenViewsLayout() { - view.addSubviews(naviBarForEditing, distanceContainerView, completeButton) + view.addSubviews(naviBarForEditing, distanceContainerView, completeButton, undoButton) view.sendSubviewToBack(naviBarForEditing) naviBarForEditing.snp.makeConstraints { make in @@ -215,6 +224,11 @@ extension CourseDrawingVC { make.center.equalToSuperview() } + undoButton.snp.makeConstraints { make in + make.trailing.equalTo(view.safeAreaLayoutGuide) + make.top.equalTo(view.snp.bottom) + } + completeButton.snp.makeConstraints { make in make.leading.trailing.equalTo(view.safeAreaLayoutGuide).inset(16) make.height.equalTo(44) @@ -223,7 +237,7 @@ extension CourseDrawingVC { } private func showHiddenViews() { - [naviBarForEditing, distanceContainerView, completeButton].forEach { subView in + [naviBarForEditing, distanceContainerView, completeButton, undoButton].forEach { subView in view.bringSubviewToFront(subView) } @@ -231,6 +245,7 @@ extension CourseDrawingVC { self.naviBarForEditing.alpha = 1 self.distanceContainerView.transform = CGAffineTransform(translationX: 0, y: -151) self.completeButton.transform = CGAffineTransform(translationX: 0, y: -112) + self.undoButton.transform = CGAffineTransform(translationX: 0, y: -(self.undoButton.frame.height+95)) } } } From dd4c1814bd3ba1a2d6b5d63e61748463e764bd28 Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Tue, 3 Jan 2023 21:47:19 +0900 Subject: [PATCH 13/13] =?UTF-8?q?[Chore]=20#24=20-=20=EB=84=A4=EC=9D=B4?= =?UTF-8?q?=EB=B2=84=20=EC=A7=80=EB=8F=84=20Logo=20=EC=9C=84=EC=B9=98=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj | 2 +- .../Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj index f762a255..8d3f7509 100644 --- a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj +++ b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj @@ -298,8 +298,8 @@ children = ( CEEC6B392961C4F300D00E1E /* CourseDrawingHomeVC.swift */, CEC2A6912962BE2900160BF7 /* DepartureSearchVC.swift */, - CEB8416F2963360800BF8080 /* CountDownVC.swift */, CE29D581296402B500F47542 /* CourseDrawingVC.swift */, + CEB8416F2963360800BF8080 /* CountDownVC.swift */, ); path = VC; sourceTree = ""; diff --git a/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift b/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift index d225a73f..135aad29 100644 --- a/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift +++ b/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift @@ -273,7 +273,7 @@ extension RNMapView { map.showLocationButton = false map.showScaleBar = false - map.mapView.logoAlign = .leftTop + map.mapView.logoAlign = .rightTop } private func getLocationAuth() {