MapKit를 사용해서 지도 앱을 만들어 보겠습니다.
이런 Component가 있는지 몰랐는데 한번 궁금해서 찾아보다가 발견해서 혼자 한번 구글링 열심히 하면서 만들어보았습니다.ㅎㅎ
역시 재미있네요🤣
💡 MapKit의 역할
1. 지도를 불러오는 기능
2. 지도의 영역(span)을 지정하는 기능
3. 지도 위 annotation(핀 등)을 관리해주는 기능
→ Apple Document에 가서 내가 원하는 기능들을 찾아보면 굉장히 간단하게 설명이 되어있고 해당 링크로 들어가면 예시들이 있기 때문에 잘 찾아서 적용해보면 좋다➿
1. UI 구성하기
Map kit view Component를 추가해서 화면에 꽉차게 구성했습니다.
후에, 위치 정보를 gps를 통해 받아올 수 있게 구현하고 싶어서 우선 라벨 두 개를 추가해줬습니다.
이렇게만 구성해줘도 2번째 사진처럼 지도가 나타난답니다.
2. 위치 정보 얻어오기
작성한 코드를 꼼꼼히 뜯어먹어보자😋
import UIKit
import CoreLocation
import MapKit
//MapKit는 지도를 확대, 축소 및 이동하는 등 지도에 관한 여러 기능을 제공한다.
//사용자의 터치를 인식하여 기능을 수행하기 위해선 이 작업이 필요하다.
class ViewController: UIViewController {
@IBOutlet weak var currentPosition: UILabel!
@IBOutlet weak var mapView: MKMapView!
var locationManager: CLLocationManager!
override func viewDidLoad() {
super.viewDidLoad()
locationManager = CLLocationManager() //객체 설정
locationManager.delegate = self //델리게이트 생성
getLocationUsagePermission() //위치 데이터를 추적하기 위해 사용자에게 승인 요구
//배터리에 맞게 권장되는 최적의 정확도
locationManager.desiredAccuracy = kCLLocationAccuracyBest
//위치 업데이트
locationManager.startUpdatingLocation()
mapView.showsCompass = true
mapView.showsUserLocation = true //위치 보기 설정
}
//위도와 경도, 스팬(영역의 폭)을 입력받아 지도에 표시
func goLocation(latitudeValue: CLLocationDegrees,
longtudeValue: CLLocationDegrees,
delta span: Double) -> CLLocationCoordinate2D {
let pLocation = CLLocationCoordinate2DMake(latitudeValue, longtudeValue)
let spanValue = MKCoordinateSpan(latitudeDelta: span, longitudeDelta: span)
let pRegion = MKCoordinateRegion(center: pLocation, span: spanValue)
mapView.setRegion(pRegion, animated: true)
return pLocation
}
}
extension ViewController: CLLocationManagerDelegate{
//위지 정보 권한 승인 요구
func getLocationUsagePermission(){
self.locationManager.requestWhenInUseAuthorization()
}
//위치 정보에서 국가, 지역, 도로를 추출해 레이블에 표시
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let pLocation = locations.last
_ = goLocation(latitudeValue: (pLocation?.coordinate.latitude)!,
longtudeValue: (pLocation?.coordinate.longitude)!,
delta: 0.01)
CLGeocoder().reverseGeocodeLocation(pLocation!, completionHandler: {(placemarks, error) -> Void in
let pm = placemarks!.first
let country = pm!.country
var address: String = ""
if country != nil {
address = country!
}
if pm!.locality != nil {
address += " "
address += pm!.locality!
}
if pm!.thoroughfare != nil {
address += " "
address += pm!.thoroughfare!
}
self.currentPosition.text = address //현재 위치 라벨에 gps 주소 넣어주기
})
locationManager.stopUpdatingLocation()
}
//💡CLLocationCoordinate2D: 지정된 위치와 관련된 위도 및 경도(struct)
//💡CLLocationCoordinate2DMake(latitude, longtude): 위도 및 경도 값을 좌표 데이터 구조 형식으로 지정하는 함수로, 위도/경도로 위치 값 저장할 수 있다.
//💡MKCoordinateSpan(latitude, longtude): 지도 영역의 너비, 높이
//💡MKCoordinateRegion(center, span): 특정 위도 및 경도를 중심으로 한 직사각형 지리적 영역
//사용자에게 gps 권한 요청에 대한 응답
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
switch status{
case .authorizedAlways, .authorizedWhenInUse:
print("GPS 권한 설정")
self.locationManager.startUpdatingLocation() //위치 업데이트 시작
case .restricted, .notDetermined:
print("GPS 권한 설정 안됨")
getLocationUsagePermission()
case .denied:
print("GPS 권한 요쳥 거부")
getLocationUsagePermission()
default:
print("default")
}
}
}
💡 CLLocation이란?
CLLocation object는 장치의 지리적 위치와 고도, 측정의 정확성을 나타내는 값과 수집 시간을 포함합니다. (iOS는 위치 객체의 코스 정보(이동 속도, 방향)도 포함)
CLLocationManager 개체에서 위치 업데이트를 요청하면, 시스템은 센서를 사용해 위치 데이터를 수집하고 해당 데이터를 앱에 보고합니다. 위치 속성에서 가장 최근에 수집된 위치를 검색할 수 있다. 사용자 지정 위치 데이터를 캐시(cache)하거나 두 지리적 좌표 사이의 거리를 계산할 때 위치 객체를 직접 작성할 수 도 있습니다.
class CLLocation : NSObject
😎 CLLocationManagerDelegate 프로토콜을 상속받아 locationManager 함수로 할 수 있는 것들이 꽤 있는데, 이번에 사용한 것들에 대해서 작성해보자!
optional func locationManager(_ manager: CLLocationManager,
didUpdateLocations locations: [CLLocation])
delegate에게 새 위치 데이터를 사용할 수 있음을 알립니다.
이 함수는 매개변수로 새 위치 데이터를 받아오기 때문에 받아온 새 위치 데이터를 이용해 어떤 기능을 추가할 수 있다.
이번에는 국가, 지역, 도로를 추출해 레이블에 표시하는 기능을 구현했다.
optional func locationManager(_ manager: CLLocationManager,
didChangeAuthorization status: CLAuthorizationStatus)
앱이 locationManager를 만들 때와 권한 부여 상태가 변경될 때 권한 부여 상태를 delegate에게 알려줍니다.
switch-case 문을 이용해서 상태를 확인하고 그에 해당하는 행동을 취하도록 합니다.
3. 지도에서 아이콘을 누르면 현재 내 위치로 이동하도록 해보자! (UIButton)
UIButton 을 추가하고 Action Function, Outlet 변수를 추가해서
1. viewDidLoad() 에서 myLocationButton의 layer.cornerRadius 곡률에 값을 줘서 모서리가 둥근 버튼으로 만들었습니다.
2. Action함수에서, 해당 버튼을 클릭하면 내 위치로 이동하도록 했습니다. (시뮬레이터는 gps 기능이 안되므로 시뮬레이터에 지정해준 위도, 경도 값으로 이동해줍니다!)
class ViewController: UIViewController {
@IBOutlet weak var myLocationButton: UIButton!
//...
override func viewDidLoad() {
super.viewDidLoad()
myLocationButton.layer.cornerRadius = 6 //버튼 둥글게~
//...
}
//...(생략)
@IBAction func tabMyLocation(_ sender: UIButton) {
locationManager.startUpdatingLocation() //내 위치로 이동
}
}
짜잔~ 어딘가로 헤매다가 내 위치를 찾는 버튼을 누르니 숙명여자대학교로 돌아왔네요 꺄울~😋
다음에는 어떤 장소를 textfield에 입력했을 때, 그 장소로 이동하는 기능을 구현해보고싶네요! 후후
💡공부 및 기록용 블로그이므로 오류가 있을 수 있습니다.💡
만약 문제에 오류나 오타가 있다면 댓글로 알려주세요➿
언제나 환영합니다. 감사합니다. 화이팅!
[참고 사이트😇]
https://moonibot.tistory.com/27
https://ios-developer-storage.tistory.com/m/entry/MKMapKit-CLCoreLocation-예시로-쉽게-이해하기-다운로드-제공
https://42kchoi.tistory.com/299
'iOS' 카테고리의 다른 글
🌱 What is MVC Design Pattern? (Stanford iOS Lecture) (0) | 2022.05.15 |
---|---|
🌱 What's in iOS? (Standford iOS Lecture) (0) | 2022.05.15 |
[iOS] 🚨 Alert 창 (0) | 2022.01.24 |
[iOS] 📎 UITableView (0) | 2022.01.24 |
[iOS] 🍽 UIStackView (0) | 2022.01.24 |