Study/Swift

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

minulbora 2024. 12. 20. 20:28

-맵 뷰란?

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

 

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다...