07 장

MapKit, Pin Annotation

//  ViewController.swift
//  DITMap

import UIKit
import MapKit

class ViewController: UIViewController, MKMapViewDelegate {
    @IBOutlet weak var myMapView: MKMapView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        //  DIT 위치정보 35.166197, 129.072594
        let center = CLLocationCoordinate2DMake(35.166197, 129.072594)
        let span = MKCoordinateSpanMake(0.05, 0.05)
        let region = MKCoordinateRegionMake(center, span)

        myMapView.setRegion(region, animated: true)

        // Annotation(Pin) 꼽기
        let anno01 = MKPointAnnotation()
        anno01.coordinate = center
        anno01.title = "DIT 동의과학대학교"
        anno01.subtitle = "나의 꿈이 자라는 곳"

        // 부산시민공원 35.168444, 129.057832
        let anno02 = MKPointAnnotation()
        anno02.coordinate.latitude = 35.168444
        anno02.coordinate.longitude = 129.057832
        anno02.title = "부산시민공원"
        anno02.subtitle = "부산시민들의 휴식처"

        myMapView.addAnnotation(anno01)
        myMapView.addAnnotation(anno02)

        myMapView.delegate = self
    }


    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {

        let identifier = "MyPin"
        var  annotationView = myMapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKPinAnnotationView

        if annotationView == nil {
            annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
            annotationView?.canShowCallout = true

            if annotation.title! == "부산시민공원" {
                annotationView?.pinTintColor = UIColor.green
            }            
        } else {
            annotationView?.annotation = annotation
        }

        let leftIconView = UIImageView(frame: CGRect(x: 0, y: 0, width: 53, height: 53))
        leftIconView.image = UIImage(named:"bright-7.png" )
        annotationView?.leftCalloutAccessoryView = leftIconView

        let btn = UIButton(type: .detailDisclosure)
        annotationView?.rightCalloutAccessoryView = btn

        return annotationView

    }

    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {

        print("callout Accessory Tapped!")

        let viewAnno = view.annotation
        let viewTitle: String = ((viewAnno?.title)!)!
        let viewSubTitle: String = ((viewAnno?.subtitle)!)!

        print("\(viewTitle) \(viewSubTitle)")

        let ac = UIAlertController(title: viewTitle, message: viewSubTitle, preferredStyle: .alert)
        ac.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
        present(ac, animated: true, completion: nil)
    }
}

CalloutAccessary Navigation

  • UIViewController을 segue를 통하여 DetailViewController와 연결한다.
  • rightCalloutAccessary Control 이벤트가 발생하면 performSegueWithIdentifier로 DetailViewController로 이이동한다.
//  Callout Accessary를 누르면 DetailView로 전환
    func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {

        if control == view.rightCalloutAccessoryView {
            self.performSegueWithIdentifier("GoDetail", sender: self)
        }
    }

다중 Pin Annotation

//  ViewPoint.swift
import MapKit
import UIKit

class ViewPoint: NSObject, MKAnnotation {

    var coordinate: CLLocationCoordinate2D
    var title: String?
    var subtitle: String?

    init(coordinate: CLLocationCoordinate2D, title: String, subtitle: String) {
        self.coordinate = coordinate
        self.title = title
        self.subtitle = subtitle
    }
}

////////////////////////////////////////////////

//  ViewController.swift
//  MultiPinMap
import UIKit
import MapKit

class ViewController: UIViewController, MKMapViewDelegate {

    @IBOutlet weak var myMapView: MKMapView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        // 지도의 center, region, Map 설정
        zoomToRegion()

        let a = ViewPoint(coordinate: CLLocationCoordinate2D(latitude: 35.104532, longitude: 129.123774), title: "오륙도 해맞이공원", subtitle: "스카이워크 걷기")
        let b = ViewPoint(coordinate: CLLocationCoordinate2D(latitude: 35.109237, longitude: 129.12652), title: "농바위", subtitle: "해안절경 바위")
        let c = ViewPoint(coordinate: CLLocationCoordinate2D(latitude: 35.11696, longitude: 129.12755), title: "치마바위", subtitle: "해안절경 바위")
        let d = ViewPoint(coordinate: CLLocationCoordinate2D(latitude: 35.123349, longitude: 129.123774), title: "어울마당",subtitle: "광안대교가 멋진곳")
        let e = ViewPoint(coordinate: CLLocationCoordinate2D(latitude: 35.12384, longitude: 129.124117), title: "해녀막사", subtitle: "해산물로 소주한잔")
        let f = ViewPoint(coordinate: CLLocationCoordinate2D(latitude: 35.127701, longitude: 129.1224), title: "구름다리", subtitle: "바닷길 다리 건너기")
        let g = ViewPoint(coordinate: CLLocationCoordinate2D(latitude: 35.133176, longitude: 129.120684), title: "동생말 전망대", subtitle: "광안리, 해운대 보기")
        myMapView.addAnnotations([a, b, c, d, e, f, g])

        myMapView.delegate = self

    }

    func zoomToRegion() {

        let location = CLLocationCoordinate2D(latitude: 35.118002, longitude: 129.121017)
        let region = MKCoordinateRegionMakeWithDistance(location, 2000.0, 4000.3)
        myMapView.setRegion(region, animated: true)
    }

    // MKMapViewDelegate method
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        let identifier = "myPin"

        // an already allocated annotation view
        var annotationView = myMapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKPinAnnotationView

        if annotationView == nil {
            annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
            annotationView?.canShowCallout = true
            let btn = UIButton(type: .detailDisclosure)
            annotationView?.rightCalloutAccessoryView = btn
            //annotationView?.pinTintColor = UIColor.green
            annotationView?.animatesDrop = true
        } else {
            annotationView?.annotation = annotation
        }

        return annotationView

    }

    // callout accessary를 눌렀을때 alert View 보여줌
    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
        let viewAnno = view.annotation //as! ViewPoint
        let placeName = viewAnno?.title
        let placeInfo = viewAnno?.subtitle

        let ac = UIAlertController(title: placeName!, message: placeInfo!, preferredStyle: .alert)
        ac.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
        present(ac, animated: true, completion: nil)
    }
}

plist 화일로 부터 데이터(POI 등) 불러오기

//  ViewController.swift
//  MapPinPLiist
//
//  Created by 김종현 on 2017. 9. 17..
//  Copyright © 2017년 김종현. All rights reserved.
//

import UIKit
import MapKit

class ViewController: UIViewController, MKMapViewDelegate {

    @IBOutlet weak var myMapView: MKMapView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        zoomToRegion()

        //////////

        let path = Bundle.main.path(forResource: "ViewPoint", ofType: "plist")
        print("path = \(String(describing: path))")

        let contents = NSArray(contentsOfFile: path!)
        print("path = \(String(describing: contents))")

        var annotations = [MKPointAnnotation]()

        if let myItems = contents {
            for item in myItems {
                let lat = (item as AnyObject).value(forKey: "lat")
                let long = (item as AnyObject).value(forKey: "long")
                let title = (item as AnyObject).value(forKey: "title")
                let subTitle = (item as AnyObject).value(forKey: "subTitle")

                let annotation = MKPointAnnotation()

                print("lat = \(String(describing: lat))")

                let myLat = (lat as! NSString).doubleValue
                let myLong = (long as! NSString).doubleValue

                print("myLat = \(myLat)")

                annotation.coordinate.latitude = myLat
                annotation.coordinate.longitude = myLong
                annotation.title = title as? String
                annotation.subtitle = subTitle as? String

                annotations.append(annotation)

                myMapView.delegate = self

            }
        }

        myMapView.showAnnotations(annotations, animated: true)

    }

    func zoomToRegion() {

        //  DIT 위치정보 35.166197, 129.072594
        let center = CLLocationCoordinate2DMake(35.166197, 129.072594)
        let span = MKCoordinateSpanMake(0.05, 0.05)
        let region = MKCoordinateRegionMake(center, span)

        myMapView.setRegion(region, animated: true)

    }

    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {

        let identifier = "MyPin"
        var  annotationView = myMapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKPinAnnotationView

        if annotationView == nil {
            annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
            annotationView?.canShowCallout = true

            if annotation.title! == "부산시민공원" {
                // 부시민공원
                annotationView?.pinTintColor = UIColor.green
                let leftIconView = UIImageView(frame: CGRect(x: 0, y: 0, width: 53, height: 53))
                leftIconView.image = UIImage(named:"citizen_logo.png" )
                annotationView?.leftCalloutAccessoryView = leftIconView

            } else if annotation.title! == "DIT 동의과학대학교" {
                // 동의과학대학교
                let leftIconView = UIImageView(frame: CGRect(x: 0, y: 0, width: 45, height: 45))
                leftIconView.image = UIImage(named:"DIT_logo.png" )
                annotationView?.leftCalloutAccessoryView = leftIconView

            } else {
                // 송상현광장
                annotationView?.pinTintColor = UIColor.blue
                let leftIconView = UIImageView(frame: CGRect(x: 0, y: 0, width: 45, height: 45))
                leftIconView.image = UIImage(named:"Songsang.png" )
                annotationView?.leftCalloutAccessoryView = leftIconView
            }
        } else {
            annotationView?.annotation = annotation
        }

        let btn = UIButton(type: .detailDisclosure)
        annotationView?.rightCalloutAccessoryView = btn

        return annotationView

    }

    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {

        print("callout Accessory Tapped!")

        let viewAnno = view.annotation
        let viewTitle: String = ((viewAnno?.title)!)!
        let viewSubTitle: String = ((viewAnno?.subtitle)!)!

        print("\(viewTitle) \(viewSubTitle)")

        let ac = UIAlertController(title: viewTitle, message: viewSubTitle, preferredStyle: .alert)
        ac.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
        present(ac, animated: true, completion: nil)
    }

}

Geocoding

address.plist

//  ViewController.swift
//  MapPinPList
//  GeoCoding
//  Created by 김종현 on 2017. 9. 17..
//  Copyright © 2017년 김종현. All rights reserved.
//

import UIKit
import MapKit

class ViewController: UIViewController, MKMapViewDelegate {

    @IBOutlet weak var myMapView: MKMapView!

    //var annotations = [MKPointAnnotation]()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        zoomToRegion()

        /////////////////////////////

        let path = Bundle.main.path(forResource: "Address2", ofType: "plist")
        print("path = \(String(describing: path))")

        let contents = NSArray(contentsOfFile: path!)
        print("path = \(String(describing: contents))")

        var annotations = [MKPointAnnotation]()

         myMapView.delegate = self

        // optional binding
        if let myItems = contents {
            // Dictionary Array에서 값 뽑기
            for item in myItems {
                let address = (item as AnyObject).value(forKey: "address")
                let title = (item as AnyObject).value(forKey: "title")

                let geoCoder = CLGeocoder()

                geoCoder.geocodeAddressString(address as! String, completionHandler: { placemarks, error in

                    if error != nil {
                        print(error!)
                        return
                    }

                    if let myPlacemarks = placemarks {
                        let myPlacemark = myPlacemarks[0]

                        print("placemark[0] = \(String(describing: myPlacemark.name))")

                        let annotation = MKPointAnnotation()
                        annotation.title = title as? String
                        annotation.subtitle = address as? String

                        if let myLocation = myPlacemark.location {
                            annotation.coordinate = myLocation.coordinate
                            annotations.append(annotation)
                        }

                    }
                    print("annotations = \(annotations)")
                    self.myMapView.showAnnotations(annotations, animated: true)
                    self.myMapView.addAnnotations(annotations)

                })
            }
        } else {
            print("contents의 값은 nil")
        }

    }

    func zoomToRegion() {

        //  DIT 위치정보 35.166197, 129.072594
        let center = CLLocationCoordinate2DMake(35.166197, 129.072594)
        let span = MKCoordinateSpanMake(0.05, 0.05)
        let region = MKCoordinateRegionMake(center, span)

        myMapView.setRegion(region, animated: true)

    }

//    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
//        
//        let identifier = "MyPin"
//        var  annotationView = myMapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKPinAnnotationView
//        
//        if annotationView == nil {
//            annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
//            annotationView?.canShowCallout = true
//            
//            if annotation.title! == "부산시민공원" {
//                // 부시민공원
//                annotationView?.pinTintColor = UIColor.green
//                let leftIconView = UIImageView(frame: CGRect(x: 0, y: 0, width: 53, height: 53))
//                leftIconView.image = UIImage(named:"citizen_logo.png" )
//                annotationView?.leftCalloutAccessoryView = leftIconView
//                
//            } else if annotation.title! == "동의과학대학교" {
//                // 동의과학대학교
//                let leftIconView = UIImageView(frame: CGRect(x: 0, y: 0, width: 45, height: 45))
//                leftIconView.image = UIImage(named:"DIT_logo.png" )
//                annotationView?.leftCalloutAccessoryView = leftIconView
//                
//            } else {
//                // 송상현광장
//                annotationView?.pinTintColor = UIColor.blue
//                let leftIconView = UIImageView(frame: CGRect(x: 0, y: 0, width: 45, height: 45))
//                leftIconView.image = UIImage(named:"Songsang.png" )
//                annotationView?.leftCalloutAccessoryView = leftIconView
//            }
//        } else {
//            annotationView?.annotation = annotation
//        }
//        
//        let btn = UIButton(type: .detailDisclosure)
//        annotationView?.rightCalloutAccessoryView = btn
//        
//        return annotationView
//        
//    }
//    
//    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
//        
//        print("callout Accessory Tapped!")
//        
//        let viewAnno = view.annotation
//        let viewTitle: String = ((viewAnno?.title)!)!
//        let viewSubTitle: String = ((viewAnno?.subtitle)!)!
//        
//        print("\(viewTitle) \(viewSubTitle)")
//        
//        let ac = UIAlertController(title: viewTitle, message: viewSubTitle, preferredStyle: .alert)
//        ac.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
//        present(ac, animated: true, completion: nil)
//    }

}
소스코드 다운로드
소스코드(plist, TableView) 다운로드

Overlay로 line 렌더링 하기

//  ViewController.swift
//  Multi-Pin Annotation & Over Line Rendering

import MapKit
import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var mapView: MKMapView!

    override func viewDidLoad() {
        super.viewDidLoad()

        zoomToRegion()

        let a = ViewPoint(title: "오륙도 해맞이공원", coordinate: CLLocationCoordinate2D(latitude: 35.104532, longitude: 129.123774), info: "스카이워크 걷기")
        let b = ViewPoint(title: "농바위", coordinate: CLLocationCoordinate2D(latitude: 35.109237, longitude: 129.12652), info: "해안절경 바위")
        let c = ViewPoint(title: "치마바위", coordinate: CLLocationCoordinate2D(latitude: 35.11696, longitude: 129.12755), info: "해안절경 바위")
        let d = ViewPoint(title: "어울마당", coordinate: CLLocationCoordinate2D(latitude: 35.123349, longitude: 129.123774), info: "광안대교가 멋진곳")
        let e = ViewPoint(title: "해녀막사", coordinate: CLLocationCoordinate2D(latitude: 35.12384, longitude: 129.124117), info: "해산물로 소주한잔")
        let f = ViewPoint(title: "구름다리", coordinate: CLLocationCoordinate2D(latitude: 35.127701, longitude: 129.1224), info: "바닷길 다리 건너기")
        let g = ViewPoint(title: "동생말 전망대", coordinate: CLLocationCoordinate2D(latitude: 35.133176, longitude: 129.120684), info: "광안리, 해운대 보기")

        let myPoint = [a, b, c, d, e, f, g]

        var myCoordinate = [a.coordinate, b.coordinate, c.coordinate, d.coordinate, e.coordinate,
                            f.coordinate, g.coordinate]

        //mapView.addAnnotations([a, b, c, d, e, f, g])
        mapView.showAnnotations(myPoint, animated: true)
        mapView.selectAnnotation(e, animated: true)

        //////
        let polyline = MKPolyline(coordinates: &myCoordinate, count: myCoordinate.count)
        mapView.addOverlay(polyline)
    }

    func zoomToRegion() {

        let location = CLLocationCoordinate2D(latitude: 35.118002, longitude: 129.121017)
        let region = MKCoordinateRegionMakeWithDistance(location, 2000.0, 4000.3)
        mapView.setRegion(region, animated: true)
    }


    func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
        // 1
        let identifier = "MyPin"

        // 사용자의 현재 위치 annotation을 제외함
        if annotation.isKindOfClass(MKUserLocation) {
            return nil
        }

        // 2
        if annotation .isKindOfClass(ViewPoint) {
            // if annotation is ViewPoint
            // 3
            var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier)

            if annotationView == nil {
                //4
                annotationView = MKPinAnnotationView(annotation:annotation, reuseIdentifier:identifier)
                annotationView!.canShowCallout = true

//                // 5
//                let btn = UIButton(type: .DetailDisclosure)
//                annotationView!.rightCalloutAccessoryView = btn
            } else {
                // 6
                annotationView!.annotation = annotation
            }

            // 5
            let btn = UIButton(type: .DetailDisclosure)
            annotationView!.rightCalloutAccessoryView = btn

            return annotationView
        }

        // 7
        return nil
    }

    func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, calloutAccessoryControlTapped control: UIControl!) {

        let viewAnno = view.annotation as! ViewPoint // MKAnnotation
        let placeName = viewAnno.title
        let placeInfo = viewAnno.info

        let ac = UIAlertController(title: placeName, message: placeInfo, preferredStyle: .Alert)
        ac.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
        presentViewController(ac, animated: true, completion: nil)
    }

    func mapView(mapView: MKMapView!, viewForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {

        if (overlay is MKPolyline) {
            let pr = MKPolylineRenderer(overlay: overlay);
            pr.strokeColor = UIColor.orangeColor().colorWithAlphaComponent(0.5);
            pr.lineWidth = 5;
            return pr;
        }

        return nil
    }
}

[코딩 문제] Busan Map Tour

  • plist 화일

  • storyboard

  • 앱 스크린

//  ViewController.swift
//  PlistToTableView
//
//  Created by 김종현 on 2017. 10. 1..
//  Copyright © 2017년 김종현. All rights reserved.
//

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var myTableView: UITableView!

    var contents = NSArray()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        myTableView.delegate = self
        myTableView.dataSource = self

        self.title = "Busan Map Tour"

        // 데이터 로드
        let path = Bundle.main.path(forResource: "Address2", ofType: "plist")
        contents = NSArray(contentsOfFile: path!)!

    }


    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return contents.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let myCell = myTableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath)

        let myTitle = (contents[indexPath.row] as AnyObject).value(forKey: "title")
        let myAddress = (contents[indexPath.row] as AnyObject).value(forKey: "address")

        print(myAddress!)

        myCell.textLabel?.text = myTitle as? String
        myCell.detailTextLabel?.text = myAddress as? String

        return myCell
    }

    // 위치정보 등 데이터를 DetailMapViewController에 전달
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "goDetail" {

            let detailMVC = segue.destination as! DetailMapViewController
            let selectedPath = myTableView.indexPathForSelectedRow

            let myIndexedTitle = (contents[(selectedPath?.row)!] as AnyObject).value(forKey: "title")
            let myIndexedAddress = (contents[(selectedPath?.row)!] as AnyObject).value(forKey: "address")

            print("myIndexedTitle = \(String(describing: myIndexedTitle))")

            detailMVC.dTitle = myIndexedTitle as? String
            detailMVC.dAddress = myIndexedAddress as? String

        } else if segue.identifier == "goTotalMap" {
            print("this is TotlMapViewController")

            let totalMVC = segue.destination as! TotalMapViewController
            totalMVC.dContents = contents

        }
    }

}
//  DetailMapViewController.swift
//  PlistToTableView
//
//  Created by 김종현 on 2017. 10. 6..
//  Copyright © 2017년 김종현. All rights reserved.
//

import UIKit
import MapKit

class DetailMapViewController: UIViewController {

    var dTitle: String?
    var dAddress: String?

    @IBOutlet weak var detailMapView: MKMapView!
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        print("dTitle = \(String(describing: dTitle))")
        print("dAddress = \(String(describing: dAddress))")

        // navigation title 설정
        self.title = dTitle

        // geoCoding
        let geoCoder = CLGeocoder()
        geoCoder.geocodeAddressString(dAddress!, completionHandler: { plackmarks, error in

            if error != nil {
                print(error!)
            }

            if plackmarks != nil {
                let myPlacemark  = plackmarks?[0]

                if (myPlacemark?.location) != nil {
                    let myLat = myPlacemark?.location?.coordinate.latitude
                    let myLong = myPlacemark?.location?.coordinate.longitude
                    let center = CLLocationCoordinate2DMake(myLat!, myLong!)
                    let span = MKCoordinateSpanMake(0.05, 0.05)
                    let region = MKCoordinateRegionMake(center, span)
                    self.detailMapView.setRegion(region, animated: true)

                    // Pin 꼽기, title, suttitle
                    let anno = MKPointAnnotation()
                    anno.title = self.dTitle
                    anno.subtitle = self.dAddress
                    anno.coordinate = (myPlacemark?.location?.coordinate)!
                    self.detailMapView.addAnnotation(anno)
                    self.detailMapView.selectAnnotation(anno, animated: true)
                }
            }

        } )

    }
}
//  TotalMapViewController.swift
//  PlistToTableView
//
//  Created by 김종현 on 2017. 10. 8..
//  Copyright © 2017년 김종현. All rights reserved.
//

import UIKit
import MapKit

class TotalMapViewController: UIViewController {

    @IBOutlet weak var totalMapView: MKMapView!
    var dContents: NSArray?

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        print("dContents = \(String(describing: dContents))")

        var annos = [MKPointAnnotation]()

        if let myItems = dContents {
            for item in myItems {
                let address = (item as AnyObject).value(forKey: "address")
                let title = (item as AnyObject).value(forKey: "title")
                let geoCoder = CLGeocoder()

                geoCoder.geocodeAddressString(address as! String, completionHandler: { placemarks, error in
                    if error != nil {
                        print(error!)
                        return
                    }

                    if let myPlacemarks = placemarks {
                        let myPlacemark = myPlacemarks[0]

                        let anno = MKPointAnnotation()
                        anno.title = title as? String
                        anno.subtitle = address as? String

                        if let myLocation = myPlacemark.location {
                            anno.coordinate = myLocation.coordinate
                            annos.append(anno)
                        }

                    }

                    self.totalMapView.showAnnotations(annos, animated: true)
                    self.totalMapView.addAnnotations(annos)
                } )
            }

            } else {
                print("dContents의 값은 nil")
            }

    }
}

소스 코드 : https://github.com/iOS-Lec-2017-1/PlistTableViewNaviGeocoding

CoreLocation

  • NSLocationAlwaysUsageDescription (항상 허용)
  • NSLocationWhenInUseUsageDescription (사용중인 경우만 허용)
//  ViewController.swift
//  Simple CoreLocation Test
import UIKit
import MapKit
import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate {

    @IBOutlet var myMapView: MKMapView!
    var locationManager = CLLocationManager()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from
        locationManager.delegate = self
        locationManager.startUpdatingLocation()
        locationManager.requestWhenInUseAuthorization()
        locationManager.startUpdatingLocation()
        locationManager.requestAlwaysAuthorization()

        myMapView.showsUserLocation = true  
    }

    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let userLocation: CLLocation = locations[0]
        print(userLocation)

        let center = CLLocationCoordinate2D(latitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude)
        let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.03, longitudeDelta: 0.03))

        myMapView.setRegion(region, animated: true)

        ////
        let annotation = MKPointAnnotation()
        annotation.coordinate = center
        annotation.title = "동의과학대학교 미래관"
        annotation.subtitle = "We Are DIT"

        myMapView.addAnnotation(annotation)
        myMapView.selectAnnotation(annotation, animated: true)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

Location Tracking : Corelocation, overlay line rendering

//  ViewController.swift
//  Location Tracker

import UIKit
import MapKit
import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate  {
    @IBOutlet var mapView: MKMapView!
    @IBOutlet var outLabel: UILabel!

    var manager: CLLocationManager!
    var myLocations: [CLLocation] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        // setup location manager
        manager = CLLocationManager()
        manager.delegate = self

        manager.desiredAccuracy = kCLLocationAccuracyBest
        manager.requestAlwaysAuthorization()
        manager.startUpdatingLocation()

        // setup MapView
        mapView.delegate = self
        //mapView.mapType = MKMapType.Hybrid
        mapView.showsUserLocation = true

        locateAndAddPin()  
    }

    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        outLabel.text = "\(locations[0])"
        myLocations.append(locations[0])

        let newRegion = MKCoordinateRegion(center: mapView.userLocation.coordinate, span: MKCoordinateSpanMake(0.015, 0.015))

        mapView.setRegion(newRegion, animated: true)

        if myLocations.count > 1 {
            let sourceIndex = myLocations.count - 1
            let destinationIndex = myLocations.count - 2
            let c1 = myLocations[sourceIndex].coordinate
            let c2 = myLocations[destinationIndex].coordinate

            print("MyLocations's count = \(myLocations.count)")
            print("source Index = \(sourceIndex)")
            print("dest Index = \(destinationIndex)")

            var a = [c1, c2]
            let polyline = MKPolyline(coordinates: &a, count: a.count)

            mapView.addOverlay(polyline)
        }
    }

    func mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer {

            let polylineRenderer = MKPolylineRenderer(overlay: overlay)
            polylineRenderer.strokeColor = UIColor.redColor()
            polylineRenderer.lineWidth = 3
            return polylineRenderer
    }

//    func mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer {
//        let pr = MKPolylineRenderer(overlay: overlay)
//        pr.strokeColor = self.lightBlue
//        pr.lineWidth = 14
//        return pr
//    }

    func locateAndAddPin() {
        // 동의과학대학교 35.165500, 129.071274
        // 위도, 경도 설정
        let center: CLLocationCoordinate2D = CLLocationCoordinate2DMake(35.165500, 129.071274)
        // 보여주는 범위 설정
        let span = MKCoordinateSpanMake(0.015, 0.015)
        // 보여주는 region 설정
        let region = MKCoordinateRegionMake(center, span)
        mapView.setRegion(region, animated: true)

        ////// annotation 꼽기
        let annotation = MKPointAnnotation()
        annotation.coordinate = center
        annotation.title = "나의 서식처"
        annotation.subtitle = " DIT"
        mapView.addAnnotation(annotation)
        mapView.selectAnnotation(annotation, animated: true)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

참고 학습자료 : current location tracking & overlay line rendering

http://www.johnmullins.co/blog/2014/08/14/location-tracker-with-maps/


2019-2 중간고사 코딩 문제

아래의 storyboard를 참고하여 코딩하세요.

(문제 1)

  • plist 화일을 작성하고, 데이터를 load하여 아래의 테이블 뷰를 만든다.

  • key : address, title

  • value :

    부산광역시 부산진구 양지로 54 동의과학대학교  
    부산광역시 부산진구 연지동 100-6 부산시민공원  
    부산광역시 부사진구 부전동 부전로 503-15 롯데호텔 부산본점
    

(문제 2)

  • 테이블뷰의 각 cell을 선택하면 아래와 같이 detailViewController에 지도를 표시한다.
  • 이때 각 cell의 주소를 goecoding하여 지도를 표시하고, pin의 title과 subtitle을 아래와 같이 설정한다.
  • NavigationBar의 title 내용도 아래와 같이 설정한다.
  • 지도의 center는 latitude: 35.164472, longitude: 129.064898로 설정하라.

(문제 3)

  • NavigationBar의 오른쪽에 UIBarButtonItem을 이용하여 아래와 같이 System Icon(Serach)를 설정한다.
  • barButtonItem Icon을 선택하면, 아래와 같이 detailViewController에 테이블뷰에 있는 모든 주소(3곳)의 지도를 아래와 같이 표시하라.
  • plist 데이터를 load하여 주소를 geocoding 하여 지도와 pin을 아래와 같이 설정한다.

(문제 4)

  • (문제 2)와 (문제 3)에 CoreLocation Framework을 사용하여 현재 위치(UserLocation)이 표시되고 위치정보를 tracking하도록 코딩하시오. 이때 현재 위치는 항상 지도의 center에 위치하도록 한다.

results matching ""

    No results matching ""