[스위프트 기초] 8강 맵 뷰로 지도 나타내기

    -맵 뷰란?

    사용자의 위치 정보를 이용하여, 위치를 지도에 표시하고 추적, 특정 위치를 표시, 사용자의 터치를 인식하여 확대, 축소 및 이동 기능 제공

     

    import UIKit
    import MapKit
    
    class ViewController: UIViewController, CLLocationManagerDelegate {
    
        @IBOutlet var lbLocationinfo1: UILabel!
        @IBOutlet var lbLocationInfo2: UILabel!
        @IBOutlet var myMap: MKMapView!
        
        let locationManager = CLLocationManager()
        
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view.
            
            lbLocationinfo1.text = ""
            lbLocationInfo2.text = ""
            locationManager.delegate = self //delegate를 self로 설정 ... ? why?
            locationManager.desiredAccuracy = kCLLocationAccuracyBest // 정확도 최고 설정
            locationManager.requestWhenInUseAuthorization() // 권한 승인 요구
            locationManager.startUpdatingLocation() //업데이트
            
            myMap.showsUserLocation = true  //위치보기값 true
            
        }
        @IBAction func sgChangeLocation(_ sender: UISegmentedControl) {
        }
        
    
    }

    Value of optional type 'CLLocation?' must be unwrapped to a value of type 'CLLocation'

    -> unwrapped 해주면 됨

        func goLocation (latitudeValue: CLLocationDegrees, longitudeValue : CLLocationDegrees, delta span : Double) {
            let pLocation = CLLocationCoordinate2D(latitude: latitudeValue, longitude: longitudeValue)
            // 위도값과 경도값을 매개변수로 하여 CLLocationCoordinatie2D 함수를 호출하고, 리턴 값을 pLocation 으로 받음
            let spanValue = MKCoordinateSpan(latitudeDelta: span, longitudeDelta: span) //pLocaion과 spanValue 값을 매개변수로 하여 MKCoordinationMake 함수를 호출하고 리턴 값을 spanValue로 받음
            let pRegion = MKCoordinateRegion(center: pLocation, span: spanValue)
            myMap.setRegion(pRegion, animated: true)
        }
        
        func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
            let pLocation = locations.last  // 위치가 업데이트되면 먼저 마지막 값을 찾아냄
            goLocation(latitudeValue: (pLocation?.coordinate.latitude)!, longitudeValue: (pLocation?.coordinate.longitude)!, delta: 0.01)
            // 강제 형변환 '!' 안붙이면 오류
            //delta 값은 지도의 크기, 값이 작을수록 확대. 1의 값에 100배로 지도를 확대해서 보여줌.
            
            CLGeocoder().reverseGeocodeLocation(pLocation!, completionHandler: {
                (placemarks, error) -> Void in
                
                if let error = error {
                    print(error)
                }
                
                //print("placemarks: "+ (placemarks.text!))
                let pm = placemarks?.first  // pm 상수로 placemark 값을 받음
                print("pm: "+(pm!.description))
                let country = pm!.country   //나라값 country 상수에 대입
                
                var add:String = country!
                if pm!.locality != nil {
                    add += " "
                    add += pm!.locality!    //지역값이 존재하면 문자열에 추가
                }
                if pm!.locality != nil{
                    add += " "
                    add += pm!.thoroughfare!    //도로 값이 존재하면 add에 추가
                }
                
                self.lbLocationinfo1.text = "현재위치"
                self.lbLocationInfo2.text = add
            })
            
            locationManager.stopUpdatingLocation()  // 위치 업데이트 멈춤
        }
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
            let pLocation = locations.last  // 위치가 업데이트되면 먼저 마지막 값을 찾아냄
            
            _=goLocation(latitudeValue: (pLocation?.coordinate.latitude)!, longitudeValue: (pLocation?.coordinate.longitude)!, delta: 0.01)
            // 강제 형변환 '!' 안붙이면 오류
            //delta 값은 지도의 크기, 값이 작을수록 확대. 1의 값에 100배로 지도를 확대해서 보여줌.
            
            CLGeocoder().reverseGeocodeLocation(pLocation!, completionHandler: {
                (placemarks, error) -> Void in
                
                if let error = error {
                    print(error)
                }
                
                //print("placemarks: "+ (placemarks.text!))
                let pm = placemarks?.first  // pm 상수로 placemark 값을 받음
                //print("pm: "+(pm!.description))
                let country = pm!.country   //나라값 country 상수에 대입
                
                var add:String = country!
                if pm!.locality != nil {
                    add += " "
                    add += pm!.locality!    //지역값이 존재하면 문자열에 추가
                }
                if pm!.locality != nil{
                    add += " "
                    add += pm!.thoroughfare!    //도로 값이 존재하면 add에 추가
                }
                
                self.lbLocationinfo1.text = "현재위치"
                self.lbLocationInfo2.text = add
            })
            
            locationManager.stopUpdatingLocation()  // 위치 업데이트 멈춤
        }
        @IBAction func sgChangeLocation(_ sender: UISegmentedControl) {
            if (sender.selectedSegmentIndex == 0){
                self.lbLocationinfo1.text=""
                self.lbLocationInfo2.text=""
                locationManager.startUpdatingLocation()
                
            }
            else if (sender.selectedSegmentIndex == 1){
                setAnnotation(latitudeValue: 37.5090394, longitudeValue: 126.9634769, delta: 0.1, title: "흑석역", subtitle: "서울특별시 동작구 현충로 지하90[흑석동 4]")
                self.lbLocationinfo1.text="보고 계신 위치"
                self.lbLocationInfo2.text="서울특별시 동작구 현충로 지하90[흑석동 4]"
            }
            else if sender.selectedSegmentIndex == 2 {
                setAnnotation(latitudeValue: 37.529706, longitudeValue: 126.964744, delta: 0.1, title: "용산역", subtitle: "서울특별시 용산구 한강대로23길 55")
                self.lbLocationinfo1.text="보고 계신 위치"
                self.lbLocationInfo2.text="서울특별시 용산구 한강대로23길 55"
            }
        }

    오류!

    원인: segment 는 0, 1, 2다...

     

     

    댓글