일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- ReLU
- 플로이드와샬
- NeuralNetwork
- Docker
- 부르트포스
- Greedy
- C++
- 실버쥐
- Blockchain
- DeepLearning
- 풀이
- Swift
- 백준
- Node.js
- 프로그래머스
- dfs
- BFS
- 그리디
- 캡스톤정리
- ios
- Algorithm
- Stack
- 탐색
- mysql
- 알고리즘
- sigmoid
- 문제풀이
- 그래프
- dp
- 백트래킹
- Today
- Total
개발아 담하자
[iOS/Swift] Apple Map 사용하기 (CLLocation으로 내 위치 이동하기, 원하는 지역으로 이동하기) 본문
지도 라이브러리로 google map, naver map 등등이 있지만, 이번 캡스톤 프로젝트는 라이브러리를 최대한❗️ 사용하지 않는 것이 목적이므로 기본 라이브러리인 MapKit 을 사용해 구현해 보았다.
MapVC 에서 구현할 기능은 크게 세 가지이다.
- 내 위치 지도에 찍기
- 주소 찾기
- 내가 원하는 지역으로 지도 이동하기
이제 구현을 시작해보자!
Add Map Kit View
Storyboard에 위 Map Kit View 를 추가하기만 하면 놀랍게도 지도가 불러와진다.
오토레이아웃이 제대로 잡혀있는지 확인하기 위해 여러 시뮬에서 돌려보았는데, Xcode가 실행중일 때는 전혀 오류가 안 나지만, Xcode 종료 후 어플을 실행하면 계속 앱이 죽는 현상이 발생했는데
self.mapView.mapType = MKMapType.standard
ViewDidLoad 에서 이 코드를 추가하니 말끔히 문제가 해결되었다.
Tracking my location
지도가 준비되었으니 이제 내 위치를 지도에 찍어보자.
Info.plist 에 NSLocationWhenInUseUsageDescription 이나 NSLocationAlwaysUsageDescription 을 추가한다.
나는 계속 에러가 발생해서 이것저것 추가하느라 세 개를 다 추가했지만 사실 저 두 개중 하나만 추가해도 앱은 잘 돌아간다 ..
내 에러는 다른 문제였다.
import CoreLocation
self.mapView.showsUserLocation = true
self.mapView.setUserTrackingMode(.follow, animated: true)
ViewDidLoad 에 이 함수만 작성해주면 지도에 내 위치 표시가 가능 하지만,, 주소 불러오기, 위도, 경도값 불러오기, 확대 등등도 해야 하므로 다른 코드들도 작성해준다. 지도에 단순 위치 표시라면 여기까지만 코드를 작성해도 무방하다.
var locationManager: CLLocationManager = CLLocationManager() // location manager
var currentLocation: CLLocation! // 내 위치 저장
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
locationManager = manager
if CLLocationManager.authorizationStatus() == .authorizedWhenInUse {
currentLocation = locationManager.location
}
}
class MapViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
locationManager.startMonitoringSignificantLocationChanges()
...
}
self.currentLocation = locationManager.location
CoreLocation 을 import 해주고, CLLocationManagerDelegate, MKMapViewDelegate 을 적는다.
location 을 관리할 CLLocationManager, 그리고 내 위치를 저장해줄 currentLocation 을 변수로 선언한다.
이 외에 locatinManager 에 여러 옵션들을 지정해준다.
// MARK : 위치 받아오기 에러 처리
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if CLLocationManager.locationServicesEnabled() {
if CLLocationManager.authorizationStatus() == .denied || CLLocationManager.authorizationStatus() == .restricted {
let alert = UIAlertController(title: "오류 발생", message: "위치 서비스 기능이 꺼져있음", preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil)
alert.addAction(okAction)
self.present(alert, animated: true, completion: nil)
} else {
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
}
} else {
let alert = UIAlertController(title: "오류 발생", message: "위치 서비스 제공 불가", preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil)
alert.addAction(okAction)
self.present(alert, animated: true, completion: nil)
}
}
위치를 받아올 때 에러가 발생하는 경우도 있으므로 에러 처리를 꼼꼼하게 해준다.
// MARK : 위치 허용 선택했을 때 처리
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .notDetermined :
manager.requestWhenInUseAuthorization()
break
case .authorizedWhenInUse:
self.firstSetting()
break
case .authorizedAlways:
self.firstSetting()
break
case .restricted :
break
case .denied :
break
default:
break
}
}
내 에러의 주범 ㅎㅎㅋㅎㅋ
바로 내 위치의 위도 경도 값을 받아올 때 자꾸 nil값이 오는 에러가 발생했는데, 위치 허용했을 때 처리를 제대로 해주지 않아서였다 .. (위치 허용 버튼을 누르기 전에는 위치값을 받아올 수 없어서 nil 값이 왔음)
firstsetting 함수는
self.currentLocation = locationManager.location
내 현재 위치를 locatioinManager.location 값을 저장하는 함수이다. 복잡해 보여서 그냥 밖으로 뺐다.
코드를 모두 작성하면 이렇게 지도에 내 위치가 뜬다.
참고로 내 위치로 다시 돌아가고 싶으면
self.mapView.showsUserLocation = true
self.mapView.setUserTrackingMode(.follow, animated: true)
원하는 action 에 다시 이 함수를 작성하면 된다.
Find Address with Coordinate
currentLocation 에 저장된 위도, 경도 값으로 내 주소를 받아오자.
// MARK : 위도, 경도에 따른 주소 찾기
func findAddr(lat: CLLocationDegrees, long: CLLocationDegrees){
let findLocation = CLLocation(latitude: lat, longitude: long)
let geocoder = CLGeocoder()
let locale = Locale(identifier: "Ko-kr")
geocoder.reverseGeocodeLocation(findLocation, preferredLocale: locale, completionHandler: {(placemarks, error) in
if let address: [CLPlacemark] = placemarks {
var myAdd: String = ""
if let area: String = address.last?.locality{
myAdd += area
}
if let name: String = address.last?.name {
myAdd += " "
myAdd += name
}
}
})
}
locale 에서 국가를 한국으로 지정하고, geocoder 로 주소를 읽어온다.
address.last?. 의 뒤에 옵션으로 주소 범위를 지정할 수 있다. 원하는 범위대로 주소를 불러오자.
Move to Search Location
이동하기 원하는 주소의 위도, 경도 값이 있을 경우에 사용 가능.
let dobongLoc = CLLocationCoordinate2D(latitude: 37.6658609, longitude: 127.0317674) // 도봉구
let eunpyeongLoc = CLLocationCoordinate2D(latitude: 37.6176125, longitude: 126.9227004) // 은평구
let dongdaemoonLoc = CLLocationCoordinate2D(latitude: 37.5838012, longitude: 127.0507003) // 동대문구
이동하기 원하는 지역의 위도,경도 값을 CLLocationCoordinate2D 에 저장해둔다.
// MARK : 검색한 위치로 이동 & marker 추가
func setMapView(coordinate: CLLocationCoordinate2D, addr: String){
let region = MKCoordinateRegion(center: coordinate, span: MKCoordinateSpan(latitudeDelta:0.01, longitudeDelta:0.01))
self.mapView.setRegion(region, animated: true)
let annotation = MKPointAnnotation()
annotation.coordinate = coordinate
annotation.title = addr
self.mapView.addAnnotation(annotation)
self.findAddr(lat: coordinate.latitude, long: coordinate.longitude)
}
MKCoordinateRegion 으로 앞서 저장해둔 CLLocationCoordinate2D 값을 좌표에 지정하고, setRegion 으로 지도의 좌표를 이동시킨다.
MKPointAnnotation 으로 원하는 곳에 mark를 찍을 수 있다.
annotation 에는 title, animation 등 여러 옵션들을 지정할 수 있다. 원하는 옵션을 지정하자.
원하는 곳으로 이동하고 좌표 찍기까지 성공 !
'📱 iOS' 카테고리의 다른 글
[iOS/Swift] tableView를 사용해 Infinite scroll 만들기 (0) | 2020.08.22 |
---|---|
[iOS/RxSwift] RxSwift 시작하기 (Observable, Subject, Operator) (0) | 2020.08.08 |
[iOS/Swift] NavigationBar with Gradient Color , 네비게이션 바 커스텀하기 (0) | 2020.06.08 |
[iOS/Swift] XML을 통한 UI 그리기 (1) (0) | 2020.05.25 |
[iOS/Swift] AVAudioPlayer 를 사용한 MusicPlayer 만들기 (0) | 2020.05.25 |