I'm currently experimenting with MapKit and SpriteKit, however I have run into a problem.
When I try to convert map coordinates to a point on my screen (in my GameScene), I get an error: Unexpectedly found nil while unwrapping an optional value
The following code produces the error and is in a function that (for testing purposes) runs when the screen is tapped.
monster.position = (mapView?.convert(spawnLocation, toPointTo: view))!
monster
is an SKSpriteNode declared at the top of my GameScene. spawnLocation
is just a set of coordinates (I checked and they should be visible on the screen). mapView
is declared at the top of my GameScene like so: var mapView = GameViewController().map
(I believe my problem is here)
Checking if mapView
contains a value or not results in nothing being printed to the console:
if (mapView != nil) {
print("not nil")
monster.position = (mapView?.convert(spawnLocation, toPointTo: view))!
}
My map shows up when I run the app, however nothing happens when the above code is executed. I think my problem is with the way I am currently accessing the map from the GameViewController, but I'm not sure how to fix it.
To clarify: my map is declared in my GameViewController and I need to access it from my GameScene so that I can convert the coordinates to a point in the view.
NOTE: I may just be using the convert function wrong.
GameViewController:
@IBOutlet var parentView: UIView!
@IBOutlet var map: MKMapView!
@IBOutlet var skview: SKView!
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
map.delegate = self
map.showsScale = false
map.showsPointsOfInterest = false
map.showsUserLocation = true
map.showsBuildings = true
map.isZoomEnabled = false
map.isScrollEnabled = false
map.isPitchEnabled = false
map.isRotateEnabled = false
locationManager.requestWhenInUseAuthorization()
if (CLLocationManager.locationServicesEnabled()) {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
}
let region = MKCoordinateRegionMakeWithDistance((locationManager.location?.coordinate)!, 400, 400)
map.setRegion(region, animated: false)
parentView.addSubview(map)
parentView.addSubview(skview)
GIDSignIn.sharedInstance().uiDelegate = self
}
So after continuing to work on my issue, I took another look at this question (I had already tried the solution in the answer - it didn't work).
I noticed that my problem might be that the scene in which I was trying to access the MKMapView
/GameViewController
from wasn't the first scene.
When I added the following to my code, it printed nil:
print("view controller", self.gameViewController)
I then looked at the code responsible for transitioning from the first scene to the one I was having issues with, and I added a line:
let signedInTransition = SKTransition.fade(withDuration: 1)
let nextScene = GameScene(size: scene!.size)
nextScene.scaleMode = .aspectFill
nextScene.gameViewController = self.gameViewController /* ADDED THIS LINE */
scene?.view?.presentScene(nextScene, transition: signedInTransition)
Turns out my problem was that my scene didn't actually have a GameViewController
and therefore
let gameViewController:GameViewController!
never actually contained a value.