From 1e1abc0de38c2add3ed9c6602835e2a292619498 Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Mon, 27 Mar 2023 00:09:29 +0900 Subject: [PATCH 1/9] =?UTF-8?q?[Feat]=20#121=20-=20=EC=A7=80=EB=8F=84=20?= =?UTF-8?q?=EC=BA=A1=EC=B3=90=20=EB=A1=9C=EC=A7=81=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xcschemes/Runnect-iOS.xcscheme | 79 +++++++++++++++++++ .../Global/Extension/UIKit+/UIImage+.swift | 31 ++++++++ .../UIComponents/MapView/RNMapView.swift | 57 ++++++------- .../Runnect-iOS/Global/Utils/adjusted+.swift | 2 +- 4 files changed, 140 insertions(+), 29 deletions(-) create mode 100644 Runnect-iOS/Runnect-iOS.xcodeproj/xcshareddata/xcschemes/Runnect-iOS.xcscheme diff --git a/Runnect-iOS/Runnect-iOS.xcodeproj/xcshareddata/xcschemes/Runnect-iOS.xcscheme b/Runnect-iOS/Runnect-iOS.xcodeproj/xcshareddata/xcschemes/Runnect-iOS.xcscheme new file mode 100644 index 00000000..911cbe3a --- /dev/null +++ b/Runnect-iOS/Runnect-iOS.xcodeproj/xcshareddata/xcschemes/Runnect-iOS.xcscheme @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIImage+.swift b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIImage+.swift index 86abf3bd..61958e84 100644 --- a/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIImage+.swift +++ b/Runnect-iOS/Runnect-iOS/Global/Extension/UIKit+/UIImage+.swift @@ -42,4 +42,35 @@ extension UIImage { UIGraphicsEndImageContext() self.init(cgImage: (image?.cgImage)!) } + + static func imageFromView(view: UIView) -> UIImage? { + UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.isOpaque, 0.0) + view.drawHierarchy(in: view.bounds, afterScreenUpdates: true) + defer { UIGraphicsEndImageContext() } + guard let context = UIGraphicsGetCurrentContext() else { return nil } + view.layer.render(in: context) + let image = UIGraphicsGetImageFromCurrentImageContext() + return image + } + + static func cropImage(_ inputImage: UIImage, toRect cropRect: CGRect, viewWidth: CGFloat, viewHeight: CGFloat) -> UIImage? { + let imageViewScale = max(inputImage.size.width / viewWidth, + inputImage.size.height / viewHeight) + + // Scale cropRect to handle images larger than shown-on-screen size + let cropZone = CGRect(x: cropRect.origin.x * imageViewScale, + y: cropRect.origin.y * imageViewScale, + width: cropRect.size.width * imageViewScale, + height: cropRect.size.height * imageViewScale) + + // Perform cropping in Core Graphics + guard let cutImageRef: CGImage = inputImage.cgImage?.cropping(to: cropZone) + else { + return nil + } + + // Return image to UIImage + let croppedImage: UIImage = UIImage(cgImage: cutImageRef) + return croppedImage + } } diff --git a/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift b/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift index 65d9c0be..201912cd 100644 --- a/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift +++ b/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift @@ -19,10 +19,13 @@ final class RNMapView: UIView { @Published var pathDistance: Double = 0 @Published var markerCount = 0 + private let screenWidth = UIScreen.main.bounds.width + private let screenHeight = UIScreen.main.bounds.height + let pathImage = PassthroughSubject() - var cancelBag = Set() + private var cancelBag = Set() - let locationManager = CLLocationManager() + private let locationManager = CLLocationManager() private var isDrawMode: Bool = false private var markers = [RNMarker]() { didSet { @@ -37,17 +40,13 @@ final class RNMapView: UIView { private var bottomPadding: CGFloat = 0 private let locationOverlayIcon = NMFOverlayImage(image: ImageLiterals.icLocationOverlay) - private lazy var dummyMap = RNMapView(frame: CGRect(x: 0, y: 0, width: 300, height: 300)).then { - $0.isUserInteractionEnabled = false - } - // MARK: - UI Components let map = NMFNaverMapView() private var startMarker = RNStartMarker() private let pathOverlay = NMFPath() private let locationButton = UIButton(type: .custom) - + // MARK: - initialization public init() { @@ -151,20 +150,18 @@ extension RNMapView { } /// 캡처를 위한 좌표 설정 및 카메라 이동 - func makeDummyMarkerAndCameraMove(at locations: [NMGLatLng]) { - addSubview(dummyMap) - sendSubviewToBack(dummyMap) - dummyMap.makeMarkersWithStartMarker(at: locations, moveCameraToStartMarker: false) + func makeCameraMoveForCapture(at locations: [NMGLatLng]) { + map.mapView.contentInset = UIEdgeInsets(top: screenHeight/4, left: 0, bottom: screenHeight/4, right: 0) let bounds = makeMBR(at: locations) let cameraUpdate = NMFCameraUpdate(fit: bounds, padding: 100) cameraUpdate.animation = .none - dummyMap.map.mapView.moveCamera(cameraUpdate) { isCancelled in + LoadingIndicator.showLoading() + map.mapView.moveCamera(cameraUpdate) { isCancelled in if isCancelled { print("카메라 이동 취소") + LoadingIndicator.hideLoading() } else { - LoadingIndicator.showLoading() - DispatchQueue.main.asyncAfter(deadline: .now()+2) { - self.dummyMap.map.mapView.zoomLevel -= 1 + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { self.makePathImage() LoadingIndicator.hideLoading() } @@ -243,26 +240,23 @@ extension RNMapView { /// 더미 뷰를 UIImage로 변환하여 pathImage에 send func makePathImage() { - self.pathImage.send(UIImage(view: dummyMap.map.mapView)) + if let image = UIImage.imageFromView(view: map.mapView) { + guard let newImage = self.cropImage(inputImage: image) else { + print("이미지 생성 실패") + return + } + self.pathImage.send(newImage) + } } /// 현재 시점까지의 마커들을 캡쳐하여 pahImage에 send func capturePathImage() { - makeDummyMarkerAndCameraMove(at: self.markersLatLngs) + makeCameraMoveForCapture(at: self.markersLatLngs) } /// 바운더리(MBR) 생성 func makeMBR(at locations: [NMGLatLng]) -> NMGLatLngBounds { - var latitudes = [Double]() - var longitudes = [Double]() - locations.forEach { latLng in - latitudes.append(latLng.lat) - longitudes.append(latLng.lng) - } - - let southWest = NMGLatLng(lat: latitudes.min() ?? 0, lng: longitudes.min() ?? 0) - let northEast = NMGLatLng(lat: latitudes.max() ?? 0, lng: longitudes.max() ?? 0) - return NMGLatLngBounds(southWest: southWest, northEast: northEast) + return NMGLatLngBounds(latLngs: locations) } /// 직전의 마커 생성을 취소하고 경로선도 제거 @@ -385,7 +379,7 @@ 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 { @@ -395,3 +389,10 @@ extension RNMapView: NMFMapViewCameraDelegate, NMFMapViewTouchDelegate { } extension RNMapView: CLLocationManagerDelegate {} + +extension RNMapView { + func cropImage(inputImage image: UIImage) -> UIImage? { + let y = screenHeight > 800 ? screenHeight/4 + 150 : screenHeight/4 - 40 + return UIImage.cropImage(image, toRect: CGRect(x: 0, y: y, width: screenWidth*2, height: 500.adjustedH), viewWidth: screenWidth, viewHeight: 400.adjustedH) + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Utils/adjusted+.swift b/Runnect-iOS/Runnect-iOS/Global/Utils/adjusted+.swift index ebe564dc..904de361 100644 --- a/Runnect-iOS/Runnect-iOS/Global/Utils/adjusted+.swift +++ b/Runnect-iOS/Runnect-iOS/Global/Utils/adjusted+.swift @@ -9,7 +9,7 @@ import UIKit /** - Description: - 스크린 너비 375를 기준으로 디자인이 나왔을 때 현재 기기의 스크린 사이즈에 비례하는 수치를 Return한다. + 스크린 너비 390를 기준으로 디자인이 나왔을 때 현재 기기의 스크린 사이즈에 비례하는 수치를 Return한다. - Note: 기기별 대응에 사용하면 된다. From 790a2086a0ec87577230b3710fbd36e0c0a533c6 Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Mon, 27 Mar 2023 10:35:49 +0900 Subject: [PATCH 2/9] =?UTF-8?q?[Feat]=20#121=20-=20GuideView=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Runnect-iOS.xcodeproj/project.pbxproj | 4 + .../Global/Literal/ImageLiterals.swift | 1 + .../ic_logo_circle.imageset/Contents.json | 26 ++++++ .../runnect logo-01 1 1.png | Bin 0 -> 3655 bytes .../runnect logo-01 1 1@2x.png | Bin 0 -> 9699 bytes .../runnect logo-01 1 1@3x.png | Bin 0 -> 18088 bytes .../Global/UIComponents/GuideView.swift | 75 ++++++++++++++++++ 7 files changed, 106 insertions(+) create mode 100644 Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_logo_circle.imageset/Contents.json create mode 100644 Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_logo_circle.imageset/runnect logo-01 1 1.png create mode 100644 Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_logo_circle.imageset/runnect logo-01 1 1@2x.png create mode 100644 Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_logo_circle.imageset/runnect logo-01 1 1@3x.png create mode 100644 Runnect-iOS/Runnect-iOS/Global/UIComponents/GuideView.swift diff --git a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj index 52b9a2f1..a30f10a5 100644 --- a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj +++ b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj @@ -116,6 +116,7 @@ CE9291252965C9FB0010959C /* CourseDetailInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE9291242965C9FB0010959C /* CourseDetailInfoView.swift */; }; CE9291272965D0ED0010959C /* StatsInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE9291262965D0ED0010959C /* StatsInfoView.swift */; }; CE9291292965E01D0010959C /* RNTimeFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE9291282965E01D0010959C /* RNTimeFormatter.swift */; }; + CEB0BCBC29D123350048CCD5 /* GuideView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEB0BCBB29D123350048CCD5 /* GuideView.swift */; }; CEB8416E2962C45300BF8080 /* LocationSearchResultTVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEB8416D2962C45300BF8080 /* LocationSearchResultTVC.swift */; }; CEB841702963360800BF8080 /* CountDownVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEB8416F2963360800BF8080 /* CountDownVC.swift */; }; CEC2A6852961F92C00160BF7 /* CustomButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC2A6842961F92C00160BF7 /* CustomButton.swift */; }; @@ -265,6 +266,7 @@ CE9291242965C9FB0010959C /* CourseDetailInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CourseDetailInfoView.swift; sourceTree = ""; }; CE9291262965D0ED0010959C /* StatsInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatsInfoView.swift; sourceTree = ""; }; CE9291282965E01D0010959C /* RNTimeFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RNTimeFormatter.swift; sourceTree = ""; }; + CEB0BCBB29D123350048CCD5 /* GuideView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GuideView.swift; sourceTree = ""; }; CEB8416D2962C45300BF8080 /* LocationSearchResultTVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationSearchResultTVC.swift; sourceTree = ""; }; CEB8416F2963360800BF8080 /* CountDownVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CountDownVC.swift; sourceTree = ""; }; CEC2A6842961F92C00160BF7 /* CustomButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomButton.swift; sourceTree = ""; }; @@ -980,6 +982,7 @@ CE9291242965C9FB0010959C /* CourseDetailInfoView.swift */, CE9291262965D0ED0010959C /* StatsInfoView.swift */, CE6B63D729673450003F900F /* ListEmptyView.swift */, + CEB0BCBB29D123350048CCD5 /* GuideView.swift */, ); path = UIComponents; sourceTree = ""; @@ -1330,6 +1333,7 @@ CECA695C296E61D6002AF05C /* PrivateCourseNotUploadedResponseDto.swift in Sources */, CE6655EC295D88D000C64E12 /* UITableView+.swift in Sources */, CEEC6B3A2961C4F300D00E1E /* CourseDrawingHomeVC.swift in Sources */, + CEB0BCBC29D123350048CCD5 /* GuideView.swift in Sources */, CEC2A6902962B06C00160BF7 /* convertLocationObject.swift in Sources */, CEC2A6852961F92C00160BF7 /* CustomButton.swift in Sources */, CE6B63D3296725E6003F900F /* CourseListCVC.swift in Sources */, diff --git a/Runnect-iOS/Runnect-iOS/Global/Literal/ImageLiterals.swift b/Runnect-iOS/Runnect-iOS/Global/Literal/ImageLiterals.swift index ae8c8e9d..b3bf5bc6 100644 --- a/Runnect-iOS/Runnect-iOS/Global/Literal/ImageLiterals.swift +++ b/Runnect-iOS/Runnect-iOS/Global/Literal/ImageLiterals.swift @@ -41,6 +41,7 @@ enum ImageLiterals { 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") } + static var icLogoCircle: UIImage { .load(named: "ic_logo_circle") } // img static var imgBackground: UIImage { .load(named: "img_background") } diff --git a/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_logo_circle.imageset/Contents.json b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_logo_circle.imageset/Contents.json new file mode 100644 index 00000000..fb29a134 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_logo_circle.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "filename" : "runnect logo-01 1 1.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "runnect logo-01 1 1@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "runnect logo-01 1 1@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "original" + } +} diff --git a/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_logo_circle.imageset/runnect logo-01 1 1.png b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_logo_circle.imageset/runnect logo-01 1 1.png new file mode 100644 index 0000000000000000000000000000000000000000..c4a60ab3833a37059f9c888716eb3195afa8024e GIT binary patch literal 3655 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 literal 0 HcmV?d00001 diff --git a/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_logo_circle.imageset/runnect logo-01 1 1@3x.png b/Runnect-iOS/Runnect-iOS/Global/Resource/Assets.xcassets/ic_logo_circle.imageset/runnect logo-01 1 1@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..efb25c9b14840680c5adb86126c678e3735ca7fb GIT binary patch literal 18088 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 Hu0mjfz=_p) literal 0 HcmV?d00001 diff --git a/Runnect-iOS/Runnect-iOS/Global/UIComponents/GuideView.swift b/Runnect-iOS/Runnect-iOS/Global/UIComponents/GuideView.swift new file mode 100644 index 00000000..482af2d6 --- /dev/null +++ b/Runnect-iOS/Runnect-iOS/Global/UIComponents/GuideView.swift @@ -0,0 +1,75 @@ +// +// GuideView.swift +// Runnect-iOS +// +// Created by sejin on 2023/03/27. +// + +import UIKit + +final class GuideView: UIView { + + // MARK: - UI Components + + private let logoImageView = UIImageView().then { + $0.image = ImageLiterals.icLogoCircle + $0.backgroundColor = .clear + } + + private let titleContainerView = UIView().then { + $0.backgroundColor = .clear + } + + private let titleLabel = UILabel().then { + $0.textColor = .black + $0.font = .b6 + $0.numberOfLines = 1 + $0.adjustsFontSizeToFitWidth = true + $0.minimumScaleFactor = 0.7 + } + + // MARK: - initialization + + init(title: String) { + super.init(frame: .zero) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + +} + +// MARK: - Methods + +extension GuideView { + private func setUI() { + self.backgroundColor = .white + self.layer.cornerRadius = 30 + self.clipsToBounds = true + self.layer.applyShadow(color: .black, alpha: 0.12, x: 0, y: 2, blur: 11, spread: 0) + } + + private func setLayout() { + self.addSubviews(logoImageView, titleContainerView) + titleContainerView.addSubviews(titleLabel) + + self.snp.makeConstraints { make in + make.height.equalTo(43) + } + + logoImageView.snp.makeConstraints { make in + make.leading.top.bottom.equalToSuperview() + } + + titleContainerView.snp.makeConstraints { make in + make.leading.equalTo(logoImageView.center) + make.top.bottom.trailing.equalToSuperview() + } + + titleLabel.snp.makeConstraints { make in + make.center.equalToSuperview() + make.leading.trailing.equalToSuperview().inset(20) + } + } +} From 37ad21e51484c353a17071b32cb92105043009ee Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Mon, 27 Mar 2023 22:12:51 +0900 Subject: [PATCH 3/9] =?UTF-8?q?[Feat]=20#121=20-=20=EC=BD=94=EC=8A=A4=20?= =?UTF-8?q?=EA=B7=B8=EB=A6=AC=EA=B8=B0=20=EB=A9=94=EC=9D=B8=EB=B7=B0?= =?UTF-8?q?=EC=97=90=20=EA=B0=80=EC=9D=B4=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/GuideView.swift | 23 ++++++++++++++----- .../VC/CourseDrawingHomeVC.swift | 9 +++++++- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/Runnect-iOS/Runnect-iOS/Global/UIComponents/GuideView.swift b/Runnect-iOS/Runnect-iOS/Global/UIComponents/GuideView.swift index 482af2d6..519b87d1 100644 --- a/Runnect-iOS/Runnect-iOS/Global/UIComponents/GuideView.swift +++ b/Runnect-iOS/Runnect-iOS/Global/UIComponents/GuideView.swift @@ -12,8 +12,11 @@ final class GuideView: UIView { // MARK: - UI Components private let logoImageView = UIImageView().then { - $0.image = ImageLiterals.icLogoCircle - $0.backgroundColor = .clear + $0.image = ImageLiterals.imgAppIcon + $0.backgroundColor = .gray + $0.contentMode = .scaleAspectFit + $0.layer.cornerRadius = 22 + $0.clipsToBounds = true } private let titleContainerView = UIView().then { @@ -26,12 +29,16 @@ final class GuideView: UIView { $0.numberOfLines = 1 $0.adjustsFontSizeToFitWidth = true $0.minimumScaleFactor = 0.7 + $0.textAlignment = .center } // MARK: - initialization init(title: String) { super.init(frame: .zero) + setUI() + setLayout() + setTitle(title: title) } required init?(coder: NSCoder) { @@ -45,7 +52,7 @@ final class GuideView: UIView { extension GuideView { private func setUI() { self.backgroundColor = .white - self.layer.cornerRadius = 30 + self.layer.cornerRadius = 22 self.clipsToBounds = true self.layer.applyShadow(color: .black, alpha: 0.12, x: 0, y: 2, blur: 11, spread: 0) } @@ -55,21 +62,25 @@ extension GuideView { titleContainerView.addSubviews(titleLabel) self.snp.makeConstraints { make in - make.height.equalTo(43) + make.width.greaterThanOrEqualTo(200) } logoImageView.snp.makeConstraints { make in make.leading.top.bottom.equalToSuperview() + make.width.height.equalTo(44) } titleContainerView.snp.makeConstraints { make in - make.leading.equalTo(logoImageView.center) + make.leading.equalTo(logoImageView.snp.centerX) make.top.bottom.trailing.equalToSuperview() } titleLabel.snp.makeConstraints { make in make.center.equalToSuperview() - make.leading.trailing.equalToSuperview().inset(20) } } + + func setTitle(title: String) { + self.titleLabel.text = title + } } diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingHomeVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingHomeVC.swift index f9452fb4..856bf47c 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingHomeVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingHomeVC.swift @@ -15,6 +15,8 @@ final class CourseDrawingHomeVC: UIViewController { // MARK: - UI Components + private let guideView = GuideView(title: "코스그리기를 눌러 나만의 코스를 만들어봐요!") + private lazy var mapView = RNMapView() .setPositionMode(mode: .normal) .makeContentPadding(padding: UIEdgeInsets(top: -calculateTopInset(), left: 0, bottom: tabBarHeight, right: 0)) @@ -58,7 +60,7 @@ extension CourseDrawingHomeVC { } private func setLayout() { - view.addSubviews(mapView, drawCourseButton) + view.addSubviews(mapView, drawCourseButton, guideView) mapView.snp.makeConstraints { make in make.top.bottom.equalToSuperview() @@ -70,5 +72,10 @@ extension CourseDrawingHomeVC { make.bottom.equalTo(view.safeAreaLayoutGuide).inset(24) make.height.equalTo(44) } + + guideView.snp.makeConstraints { make in + make.top.equalTo(view.safeAreaLayoutGuide).inset(7) + make.leading.trailing.equalTo(view.safeAreaLayoutGuide).inset(23) + } } } From 82f5e379cd0e23409125dcda9f3b0cf908789985 Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Mon, 27 Mar 2023 22:42:06 +0900 Subject: [PATCH 4/9] =?UTF-8?q?[Feat]=20#121=20-=20=EC=BD=94=EC=8A=A4=20?= =?UTF-8?q?=EA=B7=B8=EB=A6=AC=EA=B8=B0=20=EB=B7=B0=EC=97=90=20=EA=B0=80?= =?UTF-8?q?=EC=9D=B4=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/MapView/RNMapView.swift | 8 +++++++- .../CourseDrawing/VC/CourseDrawingVC.swift | 17 ++++++++++++++--- 2 files changed, 21 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 201912cd..d76afa7e 100644 --- a/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift +++ b/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift @@ -77,7 +77,6 @@ final class RNMapView: UIView { // MARK: - Methods extension RNMapView { - /// isDrawMode (편집 모드) 설정 @discardableResult func setDrawMode(to isDrawMode: Bool) -> Self { @@ -221,6 +220,13 @@ extension RNMapView { return self } + /// 네이버 지도 로고 Margin 설정 + @discardableResult + func makeNaverLogoMargin(inset: UIEdgeInsets) -> Self { + map.mapView.logoMargin = inset + return self + } + /// 현재 존재하는 Marker들 위치 리턴 func getMarkersLatLng() -> [NMGLatLng] { return self.markersLatLngs diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift index 9891e0ac..417e95ef 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift @@ -40,13 +40,15 @@ final class CourseDrawingVC: UIViewController { $0.alpha = 0 } + private let guideView = GuideView(title: "지점과 지점을 연결해 코스를 완성하세요!") + private lazy var naviBarContainerStackView = UIStackView( arrangedSubviews: [notchCoverView, naviBar] ).then { $0.axis = .vertical } - private let mapView = RNMapView() + private let mapView = RNMapView().makeNaverLogoMargin(inset: UIEdgeInsets(top: 52, left: 0, bottom: 0, right: 0)) private let departureLocationLabel = UILabel().then { $0.font = .b1 @@ -264,7 +266,7 @@ extension CourseDrawingVC { } private func setHiddenViewsLayout() { - view.addSubviews(naviBarForEditing, distanceContainerView, completeButton, undoButton) + view.addSubviews(naviBarForEditing, guideView, distanceContainerView, completeButton, undoButton) view.sendSubviewToBack(naviBarForEditing) naviBarForEditing.snp.makeConstraints { make in @@ -272,6 +274,12 @@ extension CourseDrawingVC { make.height.equalTo(48) } + guideView.snp.makeConstraints { make in + make.centerY.equalTo(naviBarForEditing.snp.centerY) + make.leading.equalTo(view.safeAreaLayoutGuide).inset(55) + make.trailing.equalTo(view.safeAreaLayoutGuide).inset(27) + } + distanceContainerView.snp.makeConstraints { make in make.width.equalTo(96) make.height.equalTo(44) @@ -298,7 +306,7 @@ extension CourseDrawingVC { } private func showHiddenViews(withDuration: TimeInterval = 0) { - [naviBarForEditing, distanceContainerView, completeButton, undoButton].forEach { subView in + [naviBarForEditing, guideView, distanceContainerView, completeButton, undoButton].forEach { subView in view.bringSubviewToFront(subView) } @@ -308,8 +316,11 @@ extension CourseDrawingVC { self.departureInfoContainerView.transform = CGAffineTransform(translationX: 0, y: 172) } + self.guideView.transform = CGAffineTransform(translationX: 0, y: -100) + UIView.animate(withDuration: withDuration) { self.naviBarForEditing.alpha = 1 + self.guideView.transform = .identity 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 3ee9343bafb2713c6b8732c237ddaedda77ed3f8 Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Mon, 27 Mar 2023 22:43:05 +0900 Subject: [PATCH 5/9] =?UTF-8?q?[Chore]=20#121=20-=20SwiftLint=20Rule=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Runnect-iOS/.swiftlint.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/Runnect-iOS/.swiftlint.yml b/Runnect-iOS/.swiftlint.yml index b4b8db1c..05d158e0 100644 --- a/Runnect-iOS/.swiftlint.yml +++ b/Runnect-iOS/.swiftlint.yml @@ -5,6 +5,7 @@ disabled_rules: - type_name - legacy_constructor - unused_setter_value + - file_length included: - Runnect-iOS From dbc418610a998d6216ccc6c5fbee244463bfca08 Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Mon, 27 Mar 2023 22:51:21 +0900 Subject: [PATCH 6/9] =?UTF-8?q?[Fix]=20#121=20-=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Runnect-iOS/Network/Router/PublicCourseRouter.swift | 2 +- .../Presentation/SignIn/VC/SignInSocialLoginVC.swift | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Runnect-iOS/Runnect-iOS/Network/Router/PublicCourseRouter.swift b/Runnect-iOS/Runnect-iOS/Network/Router/PublicCourseRouter.swift index 6e70575d..1ffa92a3 100644 --- a/Runnect-iOS/Runnect-iOS/Network/Router/PublicCourseRouter.swift +++ b/Runnect-iOS/Runnect-iOS/Network/Router/PublicCourseRouter.swift @@ -44,7 +44,7 @@ extension PublicCourseRouter: TargetType { } var task: Moya.Task { - switch  self { + switch self { case .getCourseSearchData(let keyword): return .requestParameters(parameters: ["keyword": keyword], encoding: URLEncoding.default) case .courseUploadingData(param: let param): diff --git a/Runnect-iOS/Runnect-iOS/Presentation/SignIn/VC/SignInSocialLoginVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/SignIn/VC/SignInSocialLoginVC.swift index aa2ff75e..6e856d30 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/SignIn/VC/SignInSocialLoginVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/SignIn/VC/SignInSocialLoginVC.swift @@ -83,7 +83,8 @@ extension SignInSocialLoginVC { @objc func kakaoLoginButtonDidTap(_ sender: Any) { // isKakaoTalkLoginAvailable() : 카톡 설치 되어있으면 true - if (UserApi.isKakaoTalkLoginAvailable()) { //카톡 설치되어있으면 -> 카톡으로 로그인 + if UserApi.isKakaoTalkLoginAvailable() { + // 카톡 설치되어있으면 -> 카톡으로 로그인 UserApi.shared.loginWithKakaoTalk {(oauthToken, error) in if let error = error { print(error) From c63d61c7c0f37386a19d8ba4009596f790b6c68b Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Sat, 1 Apr 2023 00:33:59 +0900 Subject: [PATCH 7/9] =?UTF-8?q?[Fix]=20#121=20-=20=ED=9A=8C=EC=9B=90?= =?UTF-8?q?=EA=B0=80=EC=9E=85=20=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 --- .../Global/Utils/RNUtils/UserManager.swift | 12 ++++++------ .../SignInDto/ResponseDto/SignInResponseDto.swift | 12 ++---------- .../Runnect-iOS/Network/Router/AuthRouter.swift | 4 ++-- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/Runnect-iOS/Runnect-iOS/Global/Utils/RNUtils/UserManager.swift b/Runnect-iOS/Runnect-iOS/Global/Utils/RNUtils/UserManager.swift index 304d071c..93811ba6 100644 --- a/Runnect-iOS/Runnect-iOS/Global/Utils/RNUtils/UserManager.swift +++ b/Runnect-iOS/Runnect-iOS/Global/Utils/RNUtils/UserManager.swift @@ -44,10 +44,10 @@ final class UserManager { do { let responseDto = try result.map(BaseResponse.self) guard let data = responseDto.data else { return } - self.accessToken = data.data.accessToken - self.refreshToken = data.data.refreshToken + self.accessToken = data.accessToken + self.refreshToken = data.refreshToken self.isKakao = provider == "KAKAO" ? true : false - completion(.success(data.data.nickname)) + completion(.success(data.nickname ?? "")) } catch { print(error.localizedDescription) completion(.failure(.networkFail)) @@ -77,10 +77,10 @@ final class UserManager { do { let responseDto = try result.map(BaseResponse.self) guard let data = responseDto.data else { return } - self.accessToken = data.data.accessToken - self.refreshToken = data.data.refreshToken + self.accessToken = data.accessToken + self.refreshToken = data.refreshToken self.isKakao = provider == "KAKAO" ? true : false - completion(.success(data.data.nickname)) + completion(.success(data.nickname ?? "")) } catch { print(error.localizedDescription) completion(.failure(.networkFail)) diff --git a/Runnect-iOS/Runnect-iOS/Network/Dto/SignInDto/ResponseDto/SignInResponseDto.swift b/Runnect-iOS/Runnect-iOS/Network/Dto/SignInDto/ResponseDto/SignInResponseDto.swift index 1e36747d..6ca13491 100644 --- a/Runnect-iOS/Runnect-iOS/Network/Dto/SignInDto/ResponseDto/SignInResponseDto.swift +++ b/Runnect-iOS/Runnect-iOS/Network/Dto/SignInDto/ResponseDto/SignInResponseDto.swift @@ -10,16 +10,8 @@ import Foundation // MARK: - SignInResponseDto struct SignInResponseDto: Codable { - let status: Int - let success: Bool - let message: String - let data: SignInResponseData -} - -// MARK: - SignInResponseData - -struct SignInResponseData: Codable { - let type, nickname, accessToken: String + let type, accessToken: String + let nickname: String? let email: String? let refreshToken: String } diff --git a/Runnect-iOS/Runnect-iOS/Network/Router/AuthRouter.swift b/Runnect-iOS/Runnect-iOS/Network/Router/AuthRouter.swift index e6f3ad40..06cfc2a8 100644 --- a/Runnect-iOS/Runnect-iOS/Network/Router/AuthRouter.swift +++ b/Runnect-iOS/Runnect-iOS/Network/Router/AuthRouter.swift @@ -39,14 +39,14 @@ extension AuthRouter: TargetType { var task: Moya.Task { switch self { case .signIn(let token, let provider): - return .requestParameters(parameters: ["token": token, "social": provider], encoding: JSONEncoding.default) + return .requestParameters(parameters: ["token": token, "provider": provider], encoding: JSONEncoding.default) } } var headers: [String: String]? { switch self { case .signIn: - return Config.headerWithAccessToken + return Config.defaultHeader } } } From dade237b1f0692349e12ee61cc2877bdc27ab7e3 Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Sat, 1 Apr 2023 10:19:34 +0900 Subject: [PATCH 8/9] =?UTF-8?q?[Chore]=20#121=20-=20=EB=8B=89=EB=84=A4?= =?UTF-8?q?=EC=9E=84=20=EC=9E=85=EB=A0=A5=20=EB=B7=B0=EC=9D=98=20api=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/Network/Router/UserRouter.swift | 7 +------ .../Presentation/SignIn/VC/NickNameSetUpVC.swift | 6 +++--- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/Runnect-iOS/Runnect-iOS/Network/Router/UserRouter.swift b/Runnect-iOS/Runnect-iOS/Network/Router/UserRouter.swift index c820973d..9da8a5be 100644 --- a/Runnect-iOS/Runnect-iOS/Network/Router/UserRouter.swift +++ b/Runnect-iOS/Runnect-iOS/Network/Router/UserRouter.swift @@ -10,7 +10,6 @@ import Foundation import Moya enum UserRouter { - case signUp(nickname: String) case getMyPageInfo case updateUserNickname(nickname: String) } @@ -26,15 +25,13 @@ extension UserRouter: TargetType { var path: String { switch self { - case .signUp, .getMyPageInfo, .updateUserNickname: + case .getMyPageInfo, .updateUserNickname: return "/user" } } var method: Moya.Method { switch self { - case .signUp: - return .post case .getMyPageInfo: return .get case .updateUserNickname: @@ -44,8 +41,6 @@ extension UserRouter: TargetType { var task: Moya.Task { switch self { - case .signUp(let nickname): - return .requestParameters(parameters: ["nickname": nickname], encoding: JSONEncoding.default) case .getMyPageInfo: return .requestPlain case .updateUserNickname(let nickname): diff --git a/Runnect-iOS/Runnect-iOS/Presentation/SignIn/VC/NickNameSetUpVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/SignIn/VC/NickNameSetUpVC.swift index 4f51f24f..6006e1e7 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/SignIn/VC/NickNameSetUpVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/SignIn/VC/NickNameSetUpVC.swift @@ -100,7 +100,7 @@ extension NickNameSetUpVC { @objc func startButtonDidTap() { guard let nickname = nicknameTextField.text else { return } - self.signIn(nickname: nickname) + self.updateUserNickname(nickname: nickname) } } @@ -150,9 +150,9 @@ extension NickNameSetUpVC: UITextFieldDelegate { // MARK: - Network extension NickNameSetUpVC { - func signIn(nickname: String) { + func updateUserNickname(nickname: String) { LoadingIndicator.showLoading() - userProvider.request(.signUp(nickname: nickname)) { [weak self] response in + userProvider.request(.updateUserNickname(nickname: nickname)) { [weak self] response in LoadingIndicator.hideLoading() guard let self = self else { return } switch response { From d0d5517c14f1a42c499253066415734948aafe64 Mon Sep 17 00:00:00 2001 From: Sejin Lee Date: Sat, 1 Apr 2023 10:47:46 +0900 Subject: [PATCH 9/9] =?UTF-8?q?[Fix]=20#121=20-=20=EC=9E=90=EB=8F=99=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EB=A1=9C=EC=A7=81=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Dto/MyPageDto/ActivityRecordInfoDto.swift | 2 +- .../Network/Dto/MyPageDto/MyPageDto.swift | 2 +- .../Runnect-iOS/Network/Router/CourseRouter.swift | 3 ++- .../Presentation/Splash/VC/SplashVC.swift | 12 ++---------- 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/Runnect-iOS/Runnect-iOS/Network/Dto/MyPageDto/ActivityRecordInfoDto.swift b/Runnect-iOS/Runnect-iOS/Network/Dto/MyPageDto/ActivityRecordInfoDto.swift index 71b8f553..1dfd6fda 100644 --- a/Runnect-iOS/Runnect-iOS/Network/Dto/MyPageDto/ActivityRecordInfoDto.swift +++ b/Runnect-iOS/Runnect-iOS/Network/Dto/MyPageDto/ActivityRecordInfoDto.swift @@ -18,7 +18,7 @@ struct ActivityRecordInfoDto: Codable { struct ActivityRecord: Codable { let id, courseId: Int let publicCourseId: Int? - let machineId, title: String + let title: String let image: String let createdAt: String let distance: Double diff --git a/Runnect-iOS/Runnect-iOS/Network/Dto/MyPageDto/MyPageDto.swift b/Runnect-iOS/Runnect-iOS/Network/Dto/MyPageDto/MyPageDto.swift index c59b0e62..3cb1bd22 100644 --- a/Runnect-iOS/Runnect-iOS/Network/Dto/MyPageDto/MyPageDto.swift +++ b/Runnect-iOS/Runnect-iOS/Network/Dto/MyPageDto/MyPageDto.swift @@ -16,6 +16,6 @@ struct MyPageDto: Codable { // MARK: - User struct User: Codable { - let machineId, nickname, latestStamp: String + let nickname, latestStamp: String let level, levelPercent: Int } diff --git a/Runnect-iOS/Runnect-iOS/Network/Router/CourseRouter.swift b/Runnect-iOS/Runnect-iOS/Network/Router/CourseRouter.swift index 2c779635..dd36f92a 100644 --- a/Runnect-iOS/Runnect-iOS/Network/Router/CourseRouter.swift +++ b/Runnect-iOS/Runnect-iOS/Network/Router/CourseRouter.swift @@ -90,7 +90,8 @@ extension CourseRouter: TargetType { switch self { case .uploadCourseDrawing: return ["Content-Type": "multipart/form-data", - "machineId": Config.deviceId] + "accessToken": Config.accessToken, + "refreshToken": Config.refreshToken] default: return Config.headerWithAccessToken } diff --git a/Runnect-iOS/Runnect-iOS/Presentation/Splash/VC/SplashVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/Splash/VC/SplashVC.swift index 9b6c2cd6..b8dc1c89 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/Splash/VC/SplashVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/Splash/VC/SplashVC.swift @@ -41,16 +41,8 @@ extension SplashVC { private func checkDidSignIn() { DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { if UserManager.shared.hasAccessToken { - UserManager.shared.autoSignIn { [weak self] result in - switch result { - case .success(let nickname): - print(nickname) - self?.pushToTabBarController() - case .failure(let error): - print(error) - self?.pushToSignInView() - } - } + // accessToken 재발급 + self.pushToTabBarController() } else { self.pushToSignInView() }