Reputation: 51
Can someone help me execute functions from one VC in another VC. The function from the first VC needs to be executed once I press a button in the second VC. Im trying with "viewcontroller().function()" function but it's not working properly, printing and basic stuff works but when it comes to stuff like drawing direction it's not working.
The function that draws directions is:
func directionToPin() {
guard let currentPlacemark = currentPlacemark else {
print("Error, the current Placemark is: \(self.currentPlacemark)")
return
}
let directionRequest = MKDirections.Request()
let destinationPlacemark = MKPlacemark(placemark: currentPlacemark)
directionRequest.source = MKMapItem.forCurrentLocation()
directionRequest.destination = MKMapItem(placemark: destinationPlacemark)
directionRequest.transportType = .walking
//calculate route
let directions = MKDirections(request: directionRequest)
directions.calculate{ (directionsResponse, error) in
guard let directionsResponse = directionsResponse else {
if let error = error {
print("error getting directions: \(error.localizedDescription)")
}
return
}
let route = directionsResponse.routes[0]
if self.drawedDriection == false {
self.drawedDriection = true
if self.didSelectAnnotation == true {
self.mapView.addOverlay(route.polyline, level: .aboveRoads)self.navigationBarController.directionButtonOutlet.setImage(UIImage(named: "navigationBarDirectionButtonRed")?.withRenderingMode(.alwaysOriginal), for: .normal)
self.mapView.setRegion(MKCoordinateRegion(routeRect), animated: true)
}
} else {
self.drawedDriection = false
self.mapView.removeOverlays(self.mapView.overlays)
if self.didSelectAnnotation == true {
self.navigationBarController.directionButtonOutlet.setImage(UIImage(named: "navigationBarDirectionButtonBlue")?.withRenderingMode(.alwaysOriginal), for: .normal)
} else {
self.navigationBarController.directionButtonOutlet.setImage(UIImage(named: "navigationBarDirectionButtonGray")?.withRenderingMode(.alwaysOriginal), for: .normal)
}
}
}
}
I'm calling the function in the second VC once I press a button:
@IBAction func directionButton(_ sender: Any) {
MapViewController().directionToPin()
}
When I run the app and press the button the currentPlacemark is nil, if I run the same function via a button in my first VC (the VC with the directionToPin function inside)
here is my repo if you need it: https://github.com/octavi42/xCodeMapsApp
Thanks!
Upvotes: 0
Views: 93
Reputation: 203
I think that you need to use Protocols and Delegates to achieve what you desire.
@IBAction func directionButton(_ sender: Any) {
MapViewController().directionToPin()
}
In the above code snippet, you are instantiating a new instance of MapViewController which upon initialization resets currentPlacemark and hence you've encountered nil.
My suggestion is to create a new protocol to communicate from MapViewController to CardViewController just like this
Add these in MapViewController.swift
protocol MapNavigationDelegate: AnyObject {
func didTapDirectionButton()
}
class MapViewController: UIViewController {
// .... Some code ....
override func viewDidLoad() {
// . .... Some more code .......
navigationBarController.mapNavigationDelegate = self
}
}
extension MapViewController: MapNavigationDelegate {
func didTapDirectionButton() {
self.directionToPin()
}
}
Add these in CardViewController.swift
class CardViewController: UIView {
// .... Some Code ....
weak var mapNavigationDelegate: MapNavigationDelegate!
@IBAction func directionButton(_ sender: Any) {
self.mapNavigationDelegate.didTapDirectionButton()
}
}
Upvotes: 2