맵뷰 어플리케이션을 만들어 보자
스토리보드를 작성하고 아웃렛변수와 액션함수를 짜줬다.
import UIKit
import MapKit
class ViewController: UIViewController {
@IBOutlet var lblLocationInfo1: UILabel!
@IBOutlet var lblLocationInfo2: UILabel!
@IBOutlet var myMap: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func sgChangeLocation(_ sender: UISegmentedControl) {
}
}
이제 코드를 짜러가자..
지도를 보여주기 위해 변수와 델리게이트를 추가하고
앱을 실행하면 지도가 나타나도록 viewDidLoad 함수에 코드를 추가하자
import UIKit
import MapKit
class ViewController: UIViewController, CLLocationManagerDelegate{
@IBOutlet var lblLocationInfo1: UILabel!
@IBOutlet var lblLocationInfo2: UILabel!
@IBOutlet var myMap: MKMapView!
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
// 우선 위치정보는 공백으로 둔다.
lblLocationInfo1.text=""
lblLocationInfo2.text=""
// 델리게이트 셀프로
locationManager.delegate = self
// 정확도 최고치
locationManager.desiredAccuracy = kCLLocationAccuracyBest
// 위치 데이터 추적을 위해 사용자에게 승인 요구
locationManager.requestWhenInUseAuthorization()
// 위치 업데이트 시작
locationManager.startUpdatingLocation()
// 위치 보기 값 true로 설정
myMap.showsUserLocation = true
}
@IBAction func sgChangeLocation(_ sender: UISegmentedControl) {
}
}
info.plist로 들어가 Privacy키를 추가하고 Value를 다음과 같이 준다
goLocation 함수
func goLocation(latitudeValue : CLLocationDegrees, longitudeValue : CLLocationDegrees, delta span :Double){
//CLLocationCoordinate2DMake : 위도와 경도를 매개변수로 하여 함수 호출 후 pLocation값을 return 받는다.
let pLocation = CLLocationCoordinate2DMake(latitudeValue, longitudeValue)
// 범위값을 매개 변수로 하여 return spanValue
let spanValue = MKCoordinateSpan(latitudeDelta: span, longitudeDelta: span)
// pLcoation, spanValue -> return pRegion
let pRegion = MKCoordinateRegion(center: pLocation, span: spanValue)
//pRegion -> call myMap.setRegion function
myMap.setRegion(pRegion, animated: true)
}
을 작성 한 후 위치가 업데이트 되었을 시 지도에 위치 나타내기 위한 함수를 통해 위에 짠 함수를 불러주자
// 위치가 업데이트되었을 때 지도에 위치 나타내는 함수
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let pLocation = locations.last //마지막 위치 찾기
//마지막 위치의 위도와 경도값을 통해 goLocation호출 delta값은 작을 수록 지도 확대 1->0.01은 100배 확대
goLocation(latitudeValue: (pLocation?.coordinate.latitude)!, longitudeValue: (pLocation?.coordinate.longitude)!, delta: 0.01)
}
그러면
func goLocation(latitudeValue : CLLocationDegrees, longitudeValue : CLLocationDegrees, delta span :Double){
//CLLocationCoordinate2DMake : 위도와 경도를 매개변수로 하여 함수 호출 후 pLocation값을 return 받는다.
let pLocation = CLLocationCoordinate2DMake(latitudeValue, longitudeValue)
// 범위값을 매개 변수로 하여 return spanValue
let spanValue = MKCoordinateSpan(latitudeDelta: span, longitudeDelta: span)
// pLcoation, spanValue -> return pRegion
let pRegion = MKCoordinateRegion(center: pLocation, span: spanValue)
//pRegion -> call myMap.setRegion function
myMap.setRegion(pRegion, animated: true)
}
// 위치가 업데이트되었을 때 지도에 위치 나타내는 함수
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let pLocation = locations.last //마지막 위치 찾기
//마지막 위치의 위도와 경도값을 통해 goLocation호출 delta값은 작을 수록 지도 확대 1->0.01은 100배 확대
goLocation(latitudeValue: (pLocation?.coordinate.latitude)!, longitudeValue: (pLocation?.coordinate.longitude)!, delta: 0.01)
}
이러면 원하는 위치를 위도와 경도로 표시할 수 있다.
위도,경도 값을 가지고
위치정보를 찾아보자 !
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let pLocation = locations.last //마지막 위치 찾기
//마지막 위치의 위도와 경도값을 통해 goLocation호출 delta값은 작을 수록 지도 확대 1->0.01은 100배 확대
goLocation(latitudeValue: (pLocation?.coordinate.latitude)!, longitudeValue: (pLocation?.coordinate.longitude)!, delta: 0.01)
//위도와 경도 값을 가지고 위치정보 찾기
CLGeocoder().reverseGeocodeLocation(pLocation!, completionHandler: {
(placemarks,error)->Void in
let pm = placemarks!.first
let country = pm!.country
var adress:String = country!
// pm상수에서 지역 값이 존재한다면 adress 문자열에 추가
if pm!.locality != nil {
adress += " "
adress += pm!.locality!
}
// pm상수에서 도로 값이 존재한다면 adress문자열에 추가
if pm!.thoroughfare != nil{
adress += " "
adress += pm!.thoroughfare!
}
self.lblLocationInfo1.text = "현재 위치"
self.lblLocationInfo2.text = adress
})
//마지막 위치 업데이트 중단
locationManager.stopUpdatingLocation()
}
핸들러의 추가함수에 adress는 나라값만 받고
지역,도로가 있다면 추가로 붙여주는 코드이다.
그러고 보면 현재 위치가 샌프라시스코로 되어 있다.
그러면 이제 현재위치를 바꿔보자
'
이런식으로 features에 들어가서 위도경도를 수정하면된다.
setAnnotation함수를 만들어준다
// 핀 설치를 위한 함수
func setAnnotation(latitudeValue : CLLocationDegrees,longitudeValue : CLLocationDegrees, delta span :Double, title strTitle:String, subtitle strSubtitle:String){
//핀 설치 위해 함수 호출 후 return 값을 annotation에 저장
let annotation = MKPointAnnotation()
//annotation의 조정값을 goLocation함수로부터 2D형태로 받아야하는데 이를 위해 goLocation함수를 수정해야한다.
annotation.coordinate = goLocation(latitudeValue: latitudeValue, longitudeValue: longitudeValue, delta: span)
}
그런데 goLocation으로부터 2D값을 받아야하니
goLocation함수를 수정해주자
func goLocation(latitudeValue : CLLocationDegrees, longitudeValue : CLLocationDegrees, delta span :Double)->CLLocationCoordinate2D{
//CLLocationCoordinate2DMake : 위도와 경도를 매개변수로 하여 함수 호출 후 pLocation값을 return 받는다.
let pLocation = CLLocationCoordinate2DMake(latitudeValue, longitudeValue)
// 범위값을 매개 변수로 하여 return spanValue
let spanValue = MKCoordinateSpan(latitudeDelta: span, longitudeDelta: span)
// pLcoation, spanValue -> return pRegion
let pRegion = MKCoordinateRegion(center: pLocation, span: spanValue)
//pRegion -> call myMap.setRegion function
myMap.setRegion(pRegion, animated: true)
//반환
return pLocation
}
반환값이 생겼다
그렇기에 locationManger함수도 수정해주자
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
...
//마지막 위치의 위도와 경도값을 통해 goLocation호출 delta값은 작을 수록 지도 확대 1->0.01은 100배 확대
// return 값 받는 함수로 변경됐으니 _=추가
_=goLocation(latitudeValue: (pLocation?.coordinate.latitude)!, longitudeValue: (pLocation?.coordinate.longitude)!, delta: 0.01)
...
함수 앞에 _=가 붙었다..!
이제 setAnnotation함수를 마무리하자
핀의 타이틀과 서브 타이틀을 입력 파라미터로 이용하여 셋팅 후 맵 뷰에 변수 annotaion값을 추가하자
func setAnnotation(latitudeValue : CLLocationDegrees,longitudeValue : CLLocationDegrees, delta span :Double, title strTitle:String, subtitle strSubtitle:String){
//핀 설치 위해 함수 호출 후 return 값을 annotation에 저장
let annotation = MKPointAnnotation()
//annotation의 조정값을 goLocation함수로부터 2D형태로 받아야하는데 이를 위해 goLocation함수를 수정해야한다.
annotation.coordinate = goLocation(latitudeValue: latitudeValue, longitudeValue: longitudeValue, delta: span)
// annotation 셋팅 후 지도에 전달
annotation.title = strTitle
annotation.subtitle = strSubtitle
myMap.addAnnotation(annotation)
}
이제 세그먼트 컨트롤의 액션을 수정하자 !
index vlaue
현재위치 : 0
동국대 : 1
DDP : 2 이다.
@IBAction func sgChangeLocation(_ sender: UISegmentedControl) {
if sender.selectedSegmentIndex == 0{
}else if sender.selectedSegmentIndex == 1{
setAnnotation(latitudeValue: 37.5591, longitudeValue: 126.9997, delta: 0.1, title: "동국대학교", subtitle: "서울특별시 중구 필동로1길 30")
self.lblLocationInfo1.text = "보고 계신 위치"
self.lblLocationInfo2.text = "동국대학교"
}else if sender.selectedSegmentIndex == 2{
setAnnotation(latitudeValue: 37.5676, longitudeValue: 127.0085, delta: 0.1, title: "DDP", subtitle: "서울특별시 중구 을지로7가 을지로 281")
self.lblLocationInfo1.text = "보고 계신 위치"
self.lblLocationInfo2.text = "DDP 동대문디자인플라자"
}
}
만들어준 setAnnotaion에 위치정보를 전달해주고 텍스트를 변경하는 코드이다.
이렇게 버튼을 누르면 표시가 잘된다.
그러면 이제 현재위치를 표시해보자
if sender.selectedSegmentIndex == 0{
//기존에 작성되어있던 텍스트 삭제
self.lblLocationInfo1.text = ""
self.lblLocationInfo2.text = ""
// 다시 원래 위치로
locationManager.startUpdatingLocation()
}
그러면
짜라랄ㄴ~
현재 위치가 잘 표시된다
전체코드는 아래와 같다
//
// ViewController.swift
// Map
//
// Created by 서희찬 on 2022/02/23.
//
import UIKit
import MapKit
class ViewController: UIViewController, CLLocationManagerDelegate{
@IBOutlet var lblLocationInfo1: UILabel!
@IBOutlet var lblLocationInfo2: UILabel!
@IBOutlet var myMap: MKMapView!
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
// 우선 위치정보는 공백으로 둔다.
lblLocationInfo1.text=""
lblLocationInfo2.text=""
// 델리게이트 셀프로
locationManager.delegate = self
// 정확도 최고치
locationManager.desiredAccuracy = kCLLocationAccuracyBest
// 위치 데이터 추적을 위해 사용자에게 승인 요구
locationManager.requestWhenInUseAuthorization()
// 위치 업데이트 시작
locationManager.startUpdatingLocation()
// 위치 보기 값 true로 설정
myMap.showsUserLocation = true
}
func goLocation(latitudeValue : CLLocationDegrees, longitudeValue : CLLocationDegrees, delta span :Double)->CLLocationCoordinate2D{
//CLLocationCoordinate2DMake : 위도와 경도를 매개변수로 하여 함수 호출 후 pLocation값을 return 받는다.
let pLocation = CLLocationCoordinate2DMake(latitudeValue, longitudeValue)
// 범위값을 매개 변수로 하여 return spanValue
let spanValue = MKCoordinateSpan(latitudeDelta: span, longitudeDelta: span)
// pLcoation, spanValue -> return pRegion
let pRegion = MKCoordinateRegion(center: pLocation, span: spanValue)
//pRegion -> call myMap.setRegion function
myMap.setRegion(pRegion, animated: true)
//반환
return pLocation
}
// 핀 설치를 위한 함수
func setAnnotation(latitudeValue : CLLocationDegrees,longitudeValue : CLLocationDegrees, delta span :Double, title strTitle:String, subtitle strSubtitle:String){
//핀 설치 위해 함수 호출 후 return 값을 annotation에 저장
let annotation = MKPointAnnotation()
//annotation의 조정값을 goLocation함수로부터 2D형태로 받아야하는데 이를 위해 goLocation함수를 수정해야한다.
annotation.coordinate = goLocation(latitudeValue: latitudeValue, longitudeValue: longitudeValue, delta: span)
// annotation 셋팅 후 지도에 전달
annotation.title = strTitle
annotation.subtitle = strSubtitle
myMap.addAnnotation(annotation)
}
// 위치가 업데이트되었을 때 지도에 위치 나타내는 함수
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let pLocation = locations.last //마지막 위치 찾기
//마지막 위치의 위도와 경도값을 통해 goLocation호출 delta값은 작을 수록 지도 확대 1->0.01은 100배 확대
// return 값 받는 함수로 변경됐으니 _=추가
_=goLocation(latitudeValue: (pLocation?.coordinate.latitude)!, longitudeValue: (pLocation?.coordinate.longitude)!, delta: 0.01)
//위도와 경도 값을 가지고 위치정보 찾기
CLGeocoder().reverseGeocodeLocation(pLocation!, completionHandler: {
(placemarks,error)->Void in
let pm = placemarks!.first
let country = pm!.country
var adress:String = country!
// pm상수에서 지역 값이 존재한다면 adress 문자열에 추가
if pm!.locality != nil {
adress += " "
adress += pm!.locality!
}
// pm상수에서 도로 값이 존재한다면 adress문자열에 추가
if pm!.thoroughfare != nil{
adress += " "
adress += pm!.thoroughfare!
}
self.lblLocationInfo1.text = "현재 위치"
self.lblLocationInfo2.text = adress
})
//마지막 위치 업데이트 중단
locationManager.stopUpdatingLocation()
}
@IBAction func sgChangeLocation(_ sender: UISegmentedControl) {
if sender.selectedSegmentIndex == 0{
//기존에 작성되어있던 텍스트 삭제
self.lblLocationInfo1.text = ""
self.lblLocationInfo2.text = ""
// 다시 원래 위치로
locationManager.startUpdatingLocation()
}else if sender.selectedSegmentIndex == 1{
setAnnotation(latitudeValue: 37.5591, longitudeValue: 126.9997, delta: 0.1, title: "동국대학교", subtitle: "서울특별시 중구 필동로1길 30")
self.lblLocationInfo1.text = "보고 계신 위치"
self.lblLocationInfo2.text = "동국대학교"
}else if sender.selectedSegmentIndex == 2{
setAnnotation(latitudeValue: 37.5676, longitudeValue: 127.0085, delta: 0.1, title: "DDP", subtitle: "서울특별시 중구 을지로7가 을지로 281")
self.lblLocationInfo1.text = "보고 계신 위치"
self.lblLocationInfo2.text = "DDP 동대문디자인플라자"
}
}
}