Change map type (hybrid, satellite) via segmented control
Asked Answered
F

3

6

I am trying to change the map type using a segmented control button, I wish for it to change the type of the map with 3 options: Standard, Satellite and Hybrid. So far I have this code but nothing happens once a different map type is selected:

@IBAction func segmentedControlAction(sender: UISegmentedControl!) {

    if sender.selectedSegmentIndex == 0{

        mapView.mapType = MKMapType.Standard
    }
    else if sender.selectedSegmentIndex == 1{

        mapView.mapType = MKMapType.Satellite
    }
    else if sender.selectedSegmentIndex == 3{

        mapView.mapType = MKMapType.Hybrid
    }
}

I am new to Swift and Xcode so any help is appreciated :)

Thanks

Florida answered 18/10, 2015 at 16:13 Comment(1)
most likely .. mapView is nil or the method isn't calledBarratry
H
24

First, ensure that your method is being called when the segmented control selection changes. It's easy to forget to hook up outlet methods. Once you've verified that, remember that map data is loaded asynchronously, so you may not see it change immediately after selecting a different mode. However, with the code you posted, you'll never see the .Hybrid type because the selectedSegmentIndex in a 3-segment control will never be 3.

A more concise way of implementing this method is:

@IBAction func segmentedControlAction(sender: UISegmentedControl!) {
    switch (sender.selectedSegmentIndex) {
        case 0:
            mapView.mapType = .Standard
        case 1:
            mapView.mapType = .Satellite
        default:
            mapView.mapType = .Hybrid
    }
}

Note that Swift doesn't need break statements at the end of each case.

Edit: Swift 4.1

@IBAction func mapTypeSegmentSelected(_ sender: UISegmentedControl) {
        switch sender.selectedSegmentIndex {
        case 0:
            mapView.mapType = .standard
        case 1:
            mapView.mapType = .satellite
        default:
            mapView.mapType = .hybrid
        }
    }
Hus answered 18/10, 2015 at 19:10 Comment(1)
is no .normal, it is: mapView.mapType = .standardBleeding
I
1
import CoreLocation
import MapKit

class ViewController: UIViewController,CLLocationManagerDelegate,MKMapViewDelegate {

    @IBOutlet weak var my_map: MKMapView!

    var my_location = CLLocationManager()

    enum maptype:NSInteger
    {
        case standardmap = 0
        case satellitemap = 1
        case hybridmap = 2
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view, typically from a nib.
        self.my_map.showsUserLocation = true
        self.my_map.delegate = self    
        self.my_location = CLLocationManager.init()
        self.my_location.delegate = self
        self.my_location.requestWhenInUseAuthorization()
        self.my_location.stopUpdatingLocation()            

        let location = CLLocationCoordinate2DMake(11.004556, 76.961632)
        let span = MKCoordinateSpanMake(0.1, 0.1)
        let region = MKCoordinateRegionMake(location, span)

        my_map.setRegion(region, animated: true)

        let annotation = MKPointAnnotation()

        annotation.coordinate = location
        annotation.title = "coimbatore"
        annotation.subtitle = "manchester city"

        my_map.addAnnotation(annotation)    
    }

    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?
    {    
        /*let annotationview = MKAnnotationView(annotation: annotation, reuseIdentifier: "pin")

        annotationview.image = UIImage(named:"nature.jpeg")

        //let transform = CGAffineTransform(scaleX: 0.1, y: 0.1)
        //annotationview.transform = transform

        return annotationview*/

        let annotationReuseId = "Place"

        var anView = mapView.dequeueReusableAnnotationView(withIdentifier: annotationReuseId)

        if anView == nil {
            anView = MKAnnotationView(annotation: annotation, reuseIdentifier: annotationReuseId)
        } else {
            anView?.annotation = annotation
        }

        anView?.image = UIImage(named: "annotation")

        let transform = CGAffineTransform(scaleX: 0.1, y: 0.1)

        anView?.transform = transform
        anView?.backgroundColor = UIColor.clear
        anView?.canShowCallout = false

        return anView
    }

    @IBAction func maptypes(_ sender: Any)
    {
        switch(sender as AnyObject).selectedSegmentIndex
        {
        case maptype.standardmap.rawValue:
            my_map.mapType = .standard
        case maptype.satellitemap.rawValue:
            my_map.mapType = .satellite
        case maptype.hybridmap.rawValue:
            my_map.mapType = .hybrid
        default:
            break
        }
    }
Inundate answered 21/12, 2017 at 8:14 Comment(1)
Usually it's better to explain a solution instead of just posting some rows of anonymous code. You can read How do I write a good answer, and also Explaining entirely code-based answersAstral
S
0

Update Swift 5.9: mapType is deprecated. Now using preferredConfiguration.

Here is an example using UIAlertController:

//Add button to navigationbar

    navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Change Map Type", style: .plain, target: self, action: #selector(mapTypeTapped))

//Setup AlertController

@objc func mapTypeTapped(){
    let ac = UIAlertController(title: "Choose map type:", message: nil, preferredStyle: .actionSheet)
    
    ac.addAction(UIAlertAction(title: "Hybrid", style: .default, handler: setMapType))
    ac.addAction(UIAlertAction(title: "Satellite", style: .default, handler: setMapType))
    ac.addAction(UIAlertAction(title: "Standard", style: .default, handler: setMapType))
    ac.addAction(UIAlertAction(title: "Cancel", style: .cancel))

    present(ac, animated: true)
    
}

//Switch the action.title

func setMapType(_ action: UIAlertAction){
    
    switch action.title {
    case "Hybrid":
        if #available(iOS 16.0, *) {
            mapView.preferredConfiguration = MKHybridMapConfiguration(elevationStyle: .realistic)
        } else {
            mapView.mapType = .hybrid
        }
    case "Satellite":
        if #available(iOS 16.0, *) {
            mapView.preferredConfiguration = MKImageryMapConfiguration(elevationStyle: .realistic)
        } else {
            mapView.mapType = .satellite
        }
    default:
        if #available(iOS 16.0, *) {
            mapView.preferredConfiguration = MKStandardMapConfiguration(elevationStyle: .realistic)
        } else {
            mapView.mapType = .standard
        }
    }
    
}
Selfmastery answered 1/10, 2024 at 20:41 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.