2015-05-25 11 views
5

Sto sviluppando un'applicazione in cui sono presenti un controller di visualizzazione e una sottoview. Nella sottoview sto caricando le mappe di Google e sulla vista principale ho un'etichetta.Invio rapido di dati dalla visualizzazione figlio al controller di visualizzazione padre

La mia domanda è come è possibile passare i dati dalla sottoview (mappa posizione geografica) all'etichetta sulla vista principale e aggiornarla man mano che la posizione viene aggiornata utilizzando Swift.

Tutte le esercitazioni che ho trovato utilizzano prepareForSegue in cui vorrei semplicemente aggiornare l'etichetta automaticamente come nella vista principale.

Grazie

Aggiornato: Io non riesco a ottenere il metodo delegato al lavoro. Codice sotto.

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); 
} 
} 
+2

il titolo e il testo don combaciare Hai una sottoview con Google Maps o è un altro controller di visualizzazione? Se quest'ultimo, l'hai aggiunto come controller di visualizzazione figlio del tuo controller di visualizzazione principale? – rdelmar

+0

Grazie. Ho aggiornato il titolo. Sto volendo inviare posizioni geografiche dalla visualizzazione figlio (che ha la mappa di Google) alla vista genitore (che ha l'etichetta). – puks1978

+0

Utilizza la delega. Rendi il controllore della vista principale, il delegato della vista, e usa il metodo di chiamata della vista (definito in un protocollo delegato) sul suo delegato quando è necessario. – rdelmar

risposta

4

delegazione modello è tuo amico.

Dichiarare un protocollo sul controller di visualizzazione figlio che verrà implementato dal controller di visualizzazione padre. Ogni volta che vuoi, chiama un metodo sul riferimento delegato che stai tenendo nel controller della vista figlio - questo aggiornerà il controller della vista genitore con i dati del VC secondario.

Questa domanda SO spiega la delegazione genitore bambino ordinatamente How do I set up a simple delegate to communicate between two view controllers?

0
var delegate:ChildViewControllerDelegate? 

In aggiunta a questo, è anche bisogno di fare questo per far funzionare il delegato:

delegate = MapController() 
3

vedo alcune risposte qui , così puoi risolvere il tuo problema cambiando alcune righe nel tuo codice, guarda:

protocol ChildViewControllerDelegate{ 
    func delegateMethod(childViewController:MapChildController, text:String) 
} 

Ho usato senza il metodo childViewController passando per metodo, quindi potevi semplicemente passare quello che vuoi inviare ad un'altra vista dicendo semplicemente che tipo di dati vuoi inviare, nel caso si tratti di una stringa. Così si può cambiare il ChildViewControllerDelegate a:

protocol ChildViewControllerDelegate{ 
    func delegateMethod(text:String) 
} 

È necessario fare la stessa cosa in classe MapController:

func delegateMethod(text: String) { 
    println("The text is " + text); 
} 

Si può vedere una spiegazione migliore in: How to send data back by popViewControllerAnimated for Swift

Problemi correlati