I am developing an app where I have a view controller and subview. On the subview I am loading Google maps and on the main view I have a label.
My question is how can I pass data from the subview (map geo location) to the label on the main view and have this updated as the location is updated using Swift.
All the tutorials I have found use prepareForSegue where I would like to just update the label automatically as it is on the main view.
Thanks
Updated: I can't seem to get the delegate method to work. Code below.
MapChildController.swift
import UIKit
protocol ChildViewControllerDelegate{
func delegateMethod(childViewController:MapChildController, text:String)
}
class MapChildController: UIViewController, CLLocationManagerDelegate {
@IBOutlet weak var mapView: GMSMapView!
let locationManager = CLLocationManager()
var didFindMyLocation = false
var myLocations: [CLLocation] = []
var delegate:ChildViewControllerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var camera = GMSCameraPosition.cameraWithLatitude(-33.86, longitude: 151.20, zoom: 15, bearing: 0, viewingAngle: 45)
var mapView = GMSMapView.mapWithFrame(CGRectZero, camera: camera)
mapView.myLocationEnabled = true
self.view = mapView
locationManager.delegate = self
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.desiredAccuracy = kCLLocationAccuracyBest
if NSProcessInfo().isOperatingSystemAtLeastVersion(NSOperatingSystemVersion(majorVersion: 8, minorVersion: 0, patchVersion: 0)) {
println("iOS >= 8.0.0")
locationManager.requestWhenInUseAuthorization()
//locationManager.requestAlwaysAuthorization()
}
mapView.addObserver(self, forKeyPath: "myLocation", options: NSKeyValueObservingOptions.New, context: nil)
locationManager.startUpdatingLocation()
//locationManager.startMonitoringSignificantLocationChanges()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) {
if !didFindMyLocation {
let myLocation: CLLocation = change[NSKeyValueChangeNewKey] as! CLLocation
var mapView = self.view as! GMSMapView
mapView.camera = GMSCameraPosition.cameraWithTarget(myLocation.coordinate, zoom: 15.0)
mapView.settings.myLocationButton = true
didFindMyLocation = true
}
}
func locationManager(manager:CLLocationManager, didUpdateLocations locations:[AnyObject]) {
// println("Last location: \(locations.last)")
self.delegate?.delegateMethod(self, text: "from child")
}
}
MapController.swift
import Foundation
import UIKit
class MapController : UIViewController, ChildViewControllerDelegate
{
@IBOutlet weak var Label: UILabel!
var LabelText = String()
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func delegateMethod(controller: MapChildController, text: String) {
println("The text is " + text);
}
}
Delegation pattern is your friend.
Declare a protocol on your child view controller that the parent view controller will implement. Whenever you want, call a method on the delegate reference you are holding in the child view controller - this will update the parent view controller with data from child VC.
This SO question explains the child parent delegation neatly How do I set up a simple delegate to communicate between two view controllers?
I see some answers here, so you can solve your problem changing some lines in your code, look at:
protocol ChildViewControllerDelegate{
func delegateMethod(childViewController:MapChildController, text:String)
}
I used without the childViewController
passing by method then you could just pass whatever you want send to another view just saying what type of data you want send, in case it's a String. So you can change the ChildViewControllerDelegate
to:
protocol ChildViewControllerDelegate{
func delegateMethod(text:String)
}
You need do the same thing in class MapController
:
func delegateMethod(text: String) {
println("The text is " + text);
}
You can see a better explanation in: How to send data back by popViewControllerAnimated for Swift
self.navigationController?.popViewController(animated: true)
let vc = self.navigationController?.viewControllers.last as! MainViewController
vc.textfield.text = "test"
you can do like if you want maybe you dont need this answer but other users for useful
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With