Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift sending data from child view to parent view controller

Tags:

ios

swift

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);
}
}
like image 853
puks1978 Avatar asked May 25 '15 04:05

puks1978


3 Answers

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?

like image 151
indrajit Avatar answered Oct 08 '22 16:10

indrajit


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

like image 20
Claudio Djohnnatha Avatar answered Oct 08 '22 17:10

Claudio Djohnnatha


 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

like image 1
ayhnhakn Avatar answered Oct 08 '22 15:10

ayhnhakn