MapView에 지도 보여주기

Posted on 2021-09-05 by GKSRUDTN99
Swift&Xcode Xcode MapView

MapView에 우리나라 지도 보여주기

1. ViewController.swift 파일을 열고, 지도를 보여주기 위해 필요한 변수와 Delegate를 선언한다.
class ViewController: UIViewController, CLLocationManagerDelegate {

    @IBOutlet var myMap: MKMapView!
    @IBOutlet var lblLocationInfo1: UILabel!
    @IBOutlet var lblLocationInfo2: UILabel!

    let locationManager = CLLocationManager()

//  (...생략...)
2. 앱을 실행하면 지도가 나타나도록 viewDidLoad 함수에 코드를 추가한다.
override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        lblLocationInfo1.text = ""
        lblLocationInfo2.text = ""
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.requestWhenInUseAuthorization()
        locationManager.startUpdatingLocation()
        myMap.showsUserLocation = true
    }
  • locationManager.desiredAccuracy - KCLLocationAccuracyBest
    • 정확도를 최고로 설정한다.
  • locationManager.requestWhenInUseAuthorization()
    • 위치 데이터를 추적하기 위해 사용자에게 승인을 요구한다.
3. Info.plist 파일 수정하기
  • Information Property List에 'Privacy - Location When In Use Usage Description'을 추가한다.
  • Value를 'App needs location servers for stuff'로 수정한다.
    • 위 Value 값은 사용자의 위치 정보를 어디에 사용하는지 작성하면 된다.

위도와 경도로 원하는 위치 표시하기

1. 위도값, 경도값, 범위를 파라미터로 받는 goLocation 함수를 viewDidLoad 함수 아래에 새로 정의한다.
func goLocation(latitudeValue: CLLOcationDegrees, longitudeValue: CLLocationDegrees, delta span: Double){

    }
2. goLocation 함수를 다음과 같이 작성한다.
func goLocation(latitudeValue: CLLocationDegrees, longitudeValue: CLLocationDegrees, delta span: Double) -> CLLocationCoordinate2D{
        let pLocation = CLLocationCoordinate2DMake(latitudeValue, longitudeValue)
        let spanValue = MKCoordinateSpan(latitudeDelta: span, longitudeDelta: span)
        let pRegion = MKCoordinateRegion(center: pLocation, span: spanValue)
        myMap.setRegion(pRegion, animated: true)
        return pLocation
    }
  • CLLocationCoordinate2DMake
    • 위도와 경도값을 받아, 두 값을 합친 CLLocationCoordinate2D 객체의 형태로 바꾼다.
  • MKCoordinateSpan
    • MapView의 가로 세로 값을 담고있는 객체이다.
  • MKCoordinateRegion
    • CLLocationCoordinated2D 객체와 MKCoordinateSpan 객체를 인수로 받아서 center 인수를 중심으로 span 만큼의 가로 세로 값을 가지는 MKCoordinateRegion 객체를 생성한다.
  • setRegion
    • MapView를 해당 위치로 옮기는 함수이다. animated가 true라면 애니메이션 효과를 적용한다.
3. goLocation 함수 아래에 지도에 위치를 표시하기 위해 locationManager Delegate 메서드를 작성한다.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let pLocation = locations.last
        _ = goLocation(latitudeValue: (pLocation?.coordinate.latitude)!, longitudeValue: (pLocation?.coordinate.longitude)!, delta: 0.01)
    }
  • 위 Delegate 메서드는 Loaction이 새롭게 바뀔때마다 실행되는 함수이다.

위치 정보 추출하여 텍스트로 표시하기

위도와 경도 값을 이용해 위치 정보를 가져오고, 나라 지역 및 도로명을 찾아 Label에 표시해본다.

1. didUpdateLocation를 파라미터를 받는 Delegate 메서드에 주소값을 가져오는 코드를 작성한다.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let pLocation = locations.last
        _ = 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 address:String = country!
            if pm!.locality != nil {
                address += " "
                address += pm!.locality!
            }
            if pm!.thoroughfare != nil {
                address += " "
                address += pm!.thoroughfare!
            }

            self.lblLocationInfo1.text = "현재 위치"
            self.lblLocationInfo2.text = address
        })

        locationManager.stopUpdatingLocation()
    }
  • CLGeocoder()
    • 좌표값과 주소값을 변환하는 기능을 제공하는 인터페이스
  • reverseGeocodeLocation
    • CLLocation 객체를 받아 주소값을 찾고, 요청이 완료되면 completionHandler를 실행한다.
    • 찾은 주소값은 CLPlacemark 객체들의 배열로, placemarks 인수에 전달된다.

원하는 위치 두 곳에 핀 설치하기

1. 핀 설치를 위한 setAnnotation gkatnfmf goLocation 함수 아래에 정의한다.
func setAnnotation(latitudeValue: CLLocationDegrees, longitudeValue: CLLocationDegrees, delta span: Double, title strTitle: String, subtitle strSubTitle:String){
        let annotation = MKPointAnnotation()
        annotation.coordinate = goLocation(latitudeValue: latitudeValue, longitudeValue: longitudeValue, delta: span)
        annotation.title = strTitle
        annotation.subtitle = strSubTitle
        myMap.addAnnotation(annotation)
    }
2. Segmented Control의 액션 수정하기
@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.557389, longitudeValue: 127.045538, delta: 1, title: "한양대학교 서울캠퍼스", subtitle: "왕십리로 222번지")
            self.lblLocationInfo1.text = "보고 계신 위치"
            self.lblLocationInfo2.text = "한양대학교"
        }
        else if sender.selectedSegmentIndex == 2 {
            setAnnotation(latitudeValue: 37.607901, longitudeValue: 127.087102, delta: 1, title: "우리 집", subtitle: "중화동 133번지")
            self.lblLocationInfo1.text = "보고 계신 위치"
            self.lblLocationInfo2.text = "우리 집"
        }
    }
  • sender.selectedSegmentIndex에는 선택된 Segment의 index 값을 담고 있다.
  • locationManger의 Delegate 메서드를 작성했으므로, UpdatingLocation을 시작하는 것 만으로 현재 위치를 나타낼 수 있다.