-
Notifications
You must be signed in to change notification settings - Fork 6
[Fix] #262 - 사용자 경험 개선을 위한 네이버맵 수정 #264
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The head ref may contain hidden characters: "#262---\uB124\uC774\uBC84\uB9F5-\uC218\uC815"
Changes from all commits
56f4326
6045943
a0c30db
daa3ab6
5ed0b8a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| { | ||
| "images" : [ | ||
| { | ||
| "filename" : "Group 9581.png", | ||
| "idiom" : "universal", | ||
| "scale" : "1x" | ||
| }, | ||
| { | ||
| "filename" : "Group 9581@2x.png", | ||
| "idiom" : "universal", | ||
| "scale" : "2x" | ||
| }, | ||
| { | ||
| "filename" : "Group 9581@3x.png", | ||
| "idiom" : "universal", | ||
| "scale" : "3x" | ||
| } | ||
| ], | ||
| "info" : { | ||
| "author" : "xcode", | ||
| "version" : 1 | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,7 +25,7 @@ final class RNMapView: UIView { | |
| private let screenHeight = UIScreen.main.bounds.height | ||
|
|
||
| let pathImage = PassthroughSubject<UIImage?, Never>() | ||
| private var cancelBag = Set<AnyCancellable>() | ||
| private var cancelBag = CancelBag() | ||
|
|
||
| private let locationManager = CLLocationManager() | ||
| private var isDrawMode: Bool = false | ||
|
|
@@ -40,7 +40,8 @@ final class RNMapView: UIView { | |
| [self.startMarker.position] + self.markers.map { $0.position } | ||
| } | ||
| private var bottomPadding: CGFloat = 0 | ||
| private let locationOverlayIcon = NMFOverlayImage(image: ImageLiterals.icLocationOverlay) | ||
| private let locationOverlayIconDirection = NMFOverlayImage(image: ImageLiterals.icLocationOverlayDirection) | ||
| private let locationOverlayIconNormal = NMFOverlayImage(image: ImageLiterals.icLocationOverlayNormal) | ||
|
|
||
| // MARK: - UI Components | ||
|
|
||
|
|
@@ -59,16 +60,17 @@ final class RNMapView: UIView { | |
| override init(frame: CGRect) { | ||
| super.init(frame: frame) | ||
| self.mapInit() | ||
| setLocationOverlay() | ||
| } | ||
|
|
||
| private func mapInit() { | ||
| setUI() | ||
| setLayout() | ||
| setBind() | ||
| setDelegate() | ||
| setMap() | ||
| getLocationAuth() | ||
| setPathOverlay() | ||
| observePositionModeChanges() | ||
| } | ||
|
|
||
| required init?(coder: NSCoder) { | ||
|
|
@@ -90,7 +92,12 @@ extension RNMapView { | |
| @discardableResult | ||
| func setPositionMode(mode: NMFMyPositionMode) -> Self { | ||
| map.mapView.positionMode = mode | ||
| setLocationOverlay() | ||
| switch mode { | ||
| case .direction: | ||
| setDirectionModeLocationOverlay() | ||
| default: | ||
| setNormalModeLocationOverLay() | ||
| } | ||
| return self | ||
| } | ||
|
|
||
|
|
@@ -154,26 +161,6 @@ extension RNMapView { | |
| return self | ||
| } | ||
|
|
||
| /// 캡처를 위한 좌표 설정 및 카메라 이동 | ||
| 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 | ||
| LoadingIndicator.showLoading() | ||
| map.mapView.moveCamera(cameraUpdate) { isCancelled in | ||
| if isCancelled { | ||
| print("카메라 이동 취소") | ||
| LoadingIndicator.hideLoading() | ||
| } else { | ||
| DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { | ||
| self.makePathImage() | ||
| LoadingIndicator.hideLoading() | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// 사용자 위치로 카메라 이동 | ||
| @discardableResult | ||
| func moveToUserLocation() -> Self { | ||
|
|
@@ -285,6 +272,26 @@ extension RNMapView { | |
| } | ||
| } | ||
|
|
||
| /// 캡처를 위한 좌표 설정 및 카메라 이동 | ||
| private 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 | ||
| LoadingIndicator.showLoading() | ||
| map.mapView.moveCamera(cameraUpdate) { isCancelled in | ||
| if isCancelled { | ||
| print("카메라 이동 취소") | ||
| LoadingIndicator.hideLoading() | ||
| } else { | ||
| DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { | ||
| self.makePathImage() | ||
| LoadingIndicator.hideLoading() | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // 두 지점 사이의 거리(m) 추가 | ||
| private func addDistance(with newLocation: NMGLatLng) { | ||
| let lastCLLoc = markersLatLngs.last?.toCLLocation() | ||
|
|
@@ -331,29 +338,62 @@ extension RNMapView { | |
| map.mapView.touchDelegate = self | ||
| } | ||
|
|
||
| private func setPathOverlay() { | ||
| private func setPathOverlay() { // 코스 path UI 설정 | ||
| pathOverlay.width = 4 | ||
| pathOverlay.outlineWidth = 0 | ||
| pathOverlay.color = .m1 | ||
| } | ||
|
|
||
| private func setLocationOverlay() { | ||
| private func setDirectionModeLocationOverlay() { | ||
| let locationOverlay = map.mapView.locationOverlay | ||
| locationOverlay.icon = locationOverlayIconDirection | ||
| } | ||
|
|
||
| private func setNormalModeLocationOverLay() { | ||
| let locationOverlay = map.mapView.locationOverlay | ||
| locationOverlay.icon = locationOverlayIcon | ||
| locationOverlay.icon = locationOverlayIconNormal | ||
| } | ||
|
|
||
| private func observePositionModeChanges() { | ||
| map.mapView.addObserver(self, forKeyPath: "positionMode", options: [.new, .old], context: nil) | ||
| } | ||
|
|
||
| override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) { | ||
| // positionMode가 변경될 때 호출됩니다. | ||
| if keyPath == "positionMode", object is NMFMapView { | ||
| DispatchQueue.main.async { [weak self] in | ||
| self?.updateStateName() | ||
| } | ||
| } | ||
| } | ||
|
Comment on lines
+361
to
+368
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 함수는 positionMode에 변경이 생기면 자동으로 호출되는 함수이고
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 네 맞습니다! 아래 |
||
|
|
||
| private func updateStateName() { | ||
| let stateStr: String | ||
| switch map.mapView.positionMode { | ||
| case .normal: | ||
| stateStr = "NoFollow" | ||
| setNormalModeLocationOverLay() | ||
| case .direction: | ||
| stateStr = "Follow" | ||
| setDirectionModeLocationOverlay() | ||
| default: | ||
| stateStr = "otherAction" | ||
| } | ||
|
|
||
| print("Position Mode: \(stateStr)") | ||
| } | ||
| } | ||
|
|
||
| // MARK: - UI & Layout | ||
|
|
||
| extension RNMapView { | ||
| private func setUI() { | ||
| private func setUI() { // 현재 위치를 찍는 아이콘의 UI 구현 | ||
| self.backgroundColor = .white | ||
| self.locationButton.setImage(ImageLiterals.icMapLocation, for: .normal) | ||
| self.locationButton.isHidden = true | ||
| self.locationButton.addTarget(self, action: #selector(locationButtonDidTap), for: .touchUpInside) | ||
| } | ||
|
|
||
| private func setLayout() { | ||
| private func setLayout() { // 지도와 현재위치 이동 버튼 의 레이아웃 구성 | ||
| addSubviews(map, locationButton) | ||
|
|
||
| map.snp.makeConstraints { | ||
|
|
@@ -373,13 +413,11 @@ extension RNMapView { | |
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // MARK: - @objc Function | ||
|
|
||
| extension RNMapView { | ||
| @objc func locationButtonDidTap() { | ||
| self.setPositionMode(mode: .direction) | ||
|
|
||
| private func setBind() { | ||
| locationButton.tapPublisher.sink { [weak self] _ in | ||
| self?.setPositionMode(mode: .direction) | ||
| }.store(in: cancelBag) | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -388,11 +426,9 @@ extension RNMapView { | |
| extension RNMapView: NMFMapViewCameraDelegate, NMFMapViewTouchDelegate { | ||
| // 지도 탭 이벤트 | ||
| func mapView(_ mapView: NMFMapView, didTapMap latlng: NMGLatLng, point: CGPoint) { | ||
| guard isDrawMode && markers.count < 19 else { return } | ||
| guard isDrawMode && markers.count < 25 else { return } | ||
| self.makeMarker(at: latlng) | ||
| } | ||
|
|
||
| func mapView(_ mapView: NMFMapView, cameraWillChangeByReason reason: Int, animated: Bool) { | ||
|
|
||
| } | ||
|
|
||
| // 지도 이동 멈췄을 때 호출되는 메서드 | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,23 +8,30 @@ | |
| import Foundation | ||
|
|
||
| // MARK: - TmapAddressSearchingResponseDto | ||
|
|
||
| struct TmapAddressSearchingResponseDto: Codable { | ||
| let addressInfo: AddressInfo | ||
|
|
||
| func toDepartureLocationModel(latitude: Double, longitude: Double) -> DepartureLocationModel { | ||
| let buildingName = self.addressInfo.buildingName.isEmpty ? "내가 설정한 출발지" : self.addressInfo.buildingName | ||
| let buildingName = self.addressInfo.buildingName.isEmpty ? "주소를 알 수 없는 출발지" : self.addressInfo.buildingName | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 문구 변경 확인했습니다 ~ |
||
|
|
||
| return DepartureLocationModel(departureName: buildingName, departureAddress: addressInfo.fullAddress, latitude: String(latitude), longitude: String(longitude)) | ||
| return DepartureLocationModel( | ||
| departureName: buildingName, | ||
| departureAddress: addressInfo.fullAddress, | ||
| latitude: String(latitude), | ||
| longitude: String(longitude) | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| // MARK: - AddressInfo | ||
|
|
||
| struct AddressInfo: Codable { | ||
| let fullAddress, addressType, cityDo, guGun: String | ||
| let eupMyun, adminDong, adminDongCode, legalDong: String | ||
| let legalDongCode, ri, bunji, roadName: String | ||
| let buildingIndex, buildingName, mappingDistance, roadCode: String | ||
|
|
||
| enum CodingKeys: String, CodingKey { | ||
| case fullAddress, addressType | ||
| case cityDo = "city_do" | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
요 부분 어떤건지 설명해줄 수 있나용 ?!?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
addObserver로 이벤트 전달을 위에 override 한 observeValue 함수로 전달하는 거예요!
observePositionModeChanges() 함수에서 keyPath "positionMode"를 해놓아서 저게 관찰이 될 때, observeValue() 함수가 호출되는 구조에요!
이 부분 참고하면 많은 도움이 될 것 같아요!
https://github.com/navermaps/ios-map-sdk/blob/117017002b9a25d39bcfc2084843ee523e4bb2d9/NaverMapDemo/LocationTrackingViewController.swift#L31
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
확인했습니다 ~~ 답장이 늦었지만 감사합니다 명진센세 !!!