hnegrao hnegrao - 1 month ago 14
Swift Question

Swift 3 - Changing map Type from a view controller to another

I am working in Xcode 8 - Swift.
I have 2 viewcontrollers: MAin Screen (first) and View Options (Second ViewController).
In the Main Screen I have a map with my location. In this screen I have a button so that the user can go to Views Screen and select what type o map he wants (this is done by a segue). The user can choose from three options: Normal, Satellite and Terrain. I implemented the second view controller has a table view of buttons. Whatever I choose it sends me to the home screen (first view controller).
I dont have another segue to send me to first view controller has I implemented a navigation controller with back buckon.

Tested this so far. Everything working ok : maps, and other things.

I created a protocol/delegate so that, when I choose what type of map I want to see in the first view controller, it sends me the information to the first. I tried send a string from the first view controller to the second and a managed to do that.
The thing is, I cannot change the map type... I dont know why but it was shows me the standard map...

Can anyone help me please?

Here is a sample of me code. Main Screen First View Controller:

class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate, DataSentDelegate {

var locationManager = CLLocationManager()

@IBOutlet var map: MKMapView!

override func viewDidLoad() {
super.viewDidLoad()

self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
self.map.showsUserLocation = true
}


func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

let userLocation: CLLocation = locations[0]
let latitude = userLocation.coordinate.latitude
let longitude = userLocation.coordinate.longitude

let latDelta: CLLocationDegrees = 0.05
let longDelta: CLLocationDegrees = 0.05

let span = MKCoordinateSpanMake(latDelta, longDelta)

let location = CLLocationCoordinate2DMake(latitude, longitude)
let region = MKCoordinateRegionMake(location, span)

self.map.setRegion(region, animated: true)

self.locationManager.stopUpdatingLocation()
}

//Protocol
func userSentView(data: String) {


switch (data) {

case "Satellite":
self.map.mapType = .satellite
break

case "Terrain":
self.map.mapType = .hybrid
break


default:
self.map.mapType = .standard
break
}

}

//Protocol
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "SegueView" {
let TVCView: TVCView = segue.destination as! TVCView
TVCView.delegate = self
}
}

}





In the second viewcontroller I have this:




protocol DataSentDelegate {
func userSentView(data: String)
}


class TVCView: UITableViewController {

var ViewNames = [String]()
var identities = [String]()

//***
var delegate: DataSentDelegate? = nil


override func viewDidLoad() {
super.viewDidLoad()

self.title = "View"

//globalView = 1;

ViewNames = ["Normal","Satellite","Terrain"]
identities = ["Normal","Satellite","Terrain"]

self.tableView.tableFooterView = UIView()

}


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


//Add names to cells

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

cell.textLabel?.text = ViewNames[indexPath.row]

return cell
}


override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

let viewController = storyboard?.instantiateViewController(withIdentifier: "Home")
self.navigationController?.pushViewController(viewController!, animated: true)


//To know which view was selected

let vcName = identities[indexPath.row]

//***
if delegate != nil {

let data = vcName
delegate?.userSentView(data: data)
dismiss(animated: true, completion: nil)

}



}




}

Answer

It looks like the problem is that you are pushing on a whole new (Home) ViewController rather than popping off the stack to the existing one.

You should remove these lines:

let viewController = storyboard?.instantiateViewController(withIdentifier: "Home")
self.navigationController?.pushViewController(viewController!, animated: true)

And replace this line:

dismiss(animated: true, completion: nil)

with:

let _ = navigationController?.popViewController(animated: true)
Comments