mapTypeChanged error (Page 115)

Hey Everyone,
I’m trying to work through the end of chapter 6 and keep getting type MapViewController has no member “mapTypeChanged” as an error. I’ve checked and re-checked the code and I can’t figure what I’m doing wrong. Below is my code so far:

import UIKit
import MapKit

class MapViewController: UIViewController {

var mapView: MKMapView!

override func loadView() {
    mapView = MKMapView()
    
    view = mapView
    
    let segmentedControl = UISegmentedControl(items: ["Standard","Hybrid","Satellite"])
    segmentedControl.backgroundColor = UIColor.white.withAlphaComponent(0.5)
    segmentedControl.selectedSegmentIndex = 0
    
    segmentedControl.addTarget(self, action: #selector(MapViewController.mapTypeChanged(_:)), for: .valueChanged)
    
    func mapTypeChanged(_ segControl: UISegmentedControl) {
        switch segControl.selectedSegmentIndex {
        case 0: mapView.mapType = .standard
        case 1: mapView.mapType = .hybrid
        case 2: mapView.mapType = .satellite
        default: break
        }
    }
    
        
    segmentedControl.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(segmentedControl)
    
    let topConstraint = segmentedControl.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor, constant: 8)
    let margins = view.layoutMarginsGuide
    let leadingConstraint = segmentedControl.leadingAnchor.constraint(equalTo: margins.leadingAnchor)
    let trailingConstraint = segmentedControl.trailingAnchor.constraint(equalTo: margins.trailingAnchor)
    
    topConstraint.isActive = true
    leadingConstraint.isActive = true
    trailingConstraint.isActive = true
    
}

override func viewDidLoad() {
    super.viewDidLoad()
    
    print("MapViewController loaded its view.")
   }
}

The mapTypeChanged function has been defined inside the loadView function.

override func loadView() {
    ...
    func mapTypeChanged(_ segControl: UISegmentedControl) {
       ...
    }
    ...
}

Make the mapTypeChanged function, just like the loadView, a method of the MapViewController class.

I KNEW it had something to do with nesting! Thanks a ton!

In Xcode 9, Swift 4, to get rid of the same error, I had to change the method signature for mapTypeChanged to:

@IBAction func mapTypeChanged(_ segControl: UISegmentedControl)

1 Like

Hello,

how would one go about doing this? I’ve typed it just as the book says but I’m not sure why it’s still an error. If you could lend some further insight, I would appreciate it. Here’s my code:

Thanks in advance!

Place the # before ‘selector’, not after.

Also, as ibex10 said above, you need to define mapTypeChanged within the class MapViewController, not within the loadView function.

I’m pretty knew to this so I am wondering what you connected the @IBAction to? Do you not have to connect it to something specific.

I do not have it connected to anything - it just needed the signature change in order to match what is expected. I just spun it up to see if it still works, and it does.

1 Like

This should be in the errata for the book.

Although it will run if you put @IBAction here, I think the proper way would be to put @objc instead. I found this from following this tip from the debugger:

Argument of ‘#selector’ refers to instance method ‘mapTypeChanged’ that is not exposed to Objective-C. Add ‘@objc’ to expose this instance method to Objective-C.