Search code examples
iosswiftmapkitmkmapview

MKMapView not rendering (just when coming from background)


I'm creating a MKMapView without storyboard. That's my ViewController class (setupLayout is called on viewDidLoad) and my MapViewController class:

// MARK: - View Controller Lifecycle
extension ViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        setupInterface()
    }

}

// MARK: - Interface
extension ViewController: Interface {

    func setupInterface() {
        setupDesign()
        setupStrings()
        setupBindings()
        setupLayout()
    }
}

Class MapViewController:

class MapViewController: ViewController {

    internal var cars: [Car]?

    // MARK: Interface Properties
    private var mapView = MKMapView(frame: .zero)

    // MARK: Internal Functions
    internal override func updateCars(cars: [Car]) {
        self.cars = cars
        placeCars()
    }
}

// MARK: - Interface
extension MapViewController {

    // MARK: Strings
    override func setupStrings() {
        super.setupStrings()

        title = Strings.mapViewTitle.localized
    }

    // MARK: Bindings
    override func setupBindings() {
        super.setupBindings()

        mapView.delegate = self
        mapView.register(CarAnnotationView.self, forAnnotationViewWithReuseIdentifier: CarAnnotationView.reuseIdentifier)
        mapView.setRegion(MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: Constants.StartCoordinates.latitude, longitude: Constants.StartCoordinates.longitude), span: MKCoordinateSpan(latitudeDelta: Constants.StartCoordinates.latitudeDelta, longitudeDelta: Constants.StartCoordinates.longitudeDelta)), animated: true)

    }

    // MARK: Layout
    override func setupLayout() {
        super.setupLayout()

        view.addSubview(mapView)
        mapView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
    }

}

The delegates methods aren't called and the map is not rendering properly:

enter image description here

If I go background and foreground again, the map works as expected. Any ideas where the problem could lay?


Solution

  • The problem was the initialisation: it needed to happen on viewDidLoad, not at the top level of the Controller.

    class MapViewController: ViewController {
    
        private var mapView: MKMapView?
    
    // ...
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        setupMapView()
    }
    
    func setupMapView() {
        mapView = MKMapView(frame: .zero)
        mapView?.delegate = self
        mapView?.register(CarAnnotationView.self, forAnnotationViewWithReuseIdentifier: CarAnnotationView.reuseIdentifier)
        mapView?.setRegion(MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: Constants.StartCoordinates.latitude, longitude: Constants.StartCoordinates.longitude), span: MKCoordinateSpan(latitudeDelta: Constants.StartCoordinates.latitudeDelta, longitudeDelta: Constants.StartCoordinates.longitudeDelta)), animated: true)
    
        guard let mapView = mapView else { return }
        view.addSubview(mapView)
        mapView.snp.remakeConstraints { make in
            make.edges.equalToSuperview()
        }
    }