2014-08-27 8 views
13

Un paio di settimane fa ho chiesto la domanda this e ho ottenuto una spiegazione molto dettagliata. Ora vorrei passare i dati al primo ViewController ma continuo a rimanere bloccato usando lo stesso metodo. Ho un modale del primo VC al secondo, in cui vorrei modificare una serie di stringhe, che verranno mostrate di nuovo alla prima vista. Quindi alla mia prima vista ho una matrice di dati, che dovrebbe essere passata al secondo, in modo che i campi di modifica mostrino le informazioni correnti dopo le quali l'utente deve essere in grado di modificare il contenuto dell'array e trasferire tali dati al primo dove è mostrato sulle etichette. Sto usando Swift.Passaggio dei dati dai controller di vista Xcode

Il mio codice:

(in ViewController.swift :)

override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) { 
     let secondVC = segue.destinationViewController as SecondViewController 
     secondVC.namesPlayers = self.namesPlayers 
    } 

(in SecondViewController.swift :)

override func viewDidLoad() { 
    super.viewDidLoad() 
    labelFirstPlayer.text = namenSpelers[0] 
} 

Grazie

+0

Dov'è il tuo codice? – Raptor

+0

Spiacente, ho aggiornato il mio OP –

risposta

36

È necessario utilizzare un delegare. Ecco un esempio di come utilizzare un delegato in Swift.

Sul tuo primo ViewController, impostare il delegato quando si carica il secondo VC:

Ad esempio, se si utilizza l'Editor Storyboard:

var secondViewController = (segue.destinationViewController.visibleViewController as MySecondViewControllerClass) 
secondViewController.delegate = self 

Scrivi un protocollo e definire un func di scrivere si torna valori

Ad esempio, creare un file chiamato "Protocol.swift" e scrivere qualcosa di simile:

protocol writeValueBackDelegate { 
    func writeValueBack(value: String) 
} 

aggiungere la funzione al vostro FirstViewController

func writeValueBack(value: String) { 
    // Or any other function you need to transport data 
} 

E per i tuoi ViewControllerClass

class ViewController: UIViewController, writeValueBackDelegate 

La linea di cui sopra non funziona se non è stato implementato tutti i metodi in ViewController che si è definito nel protocollo file.

Vai al secondo controller di vista, e aggiungere il delegato qui:

class SecondViewController: ViewController { 

    // Delegate for FirstViewController 
    // Declare as weak to avoid memory cycles 
    weak var delegate: writeValueBackDelegate? 
} 

Sul secondo controller di vista, è ora possibile utilizzare questo per chiamare il func nel primo View Controller un dato passa.

+0

Devi anche indicare che il tuo primo controller di visualizzazione implementa il protocollo: 'classe ViewController: UIViewController, writeValueBackDelegate {' – vacawama

+0

Grazie, ho dimenticato. Modifica il mio thread – derdida

+0

Non possiamo usare le chiusure qui per ottenere lo stesso risultato? – Satyam

0

Sono confuso dalla risposta usando i delegati, perché mi sembra inutilmente complicato. Ecco cosa ho fatto per aprire una finestra di dialogo Aggiungi giocatore nel mio gioco di carte e passare i risultati al controller di visualizzazione della chiamata.

protocollo aggiuntivo delegato (nel mio caso nel mio file di estensioni/Protocolli)

protocol ReturnPlayerInfoDelegate { 
    func returnPlayerInfo(playerName : String, playerType : Player.Type) 
} 

Poi ho aggiunto il mio riferimento (come classe var) al delegato nel controller vista chiamata.Nota: questo non ha richiesto il mio sottoclasse il mio interlocutore, o l'aggiunta del protocollo alla mia chiamata View Controller:

class AddPlayerViewController : UIViewController { 
    static var delegate : ReturnPlayerInfoDelegate! 

e chiamato il delegato nel mio gestore del pulsante Ok:

@IBAction func onOK(sender: UIButton) { 
     AddPlayerViewController.delegate.returnPlayerInfo(mPlayerName.text!, playerType: mPlayerTypeActual) 
    dismissViewControllerAnimated(true, completion: nil) 
} 

Ora ho implementato il delegato in CALLING ViewController:

class FiveKings : UIViewController, UIGestureRecognizerDelegate, UIPopoverPresentationControllerDelegate ,UITextViewDelegate , ReturnPlayerInfoDelegate { 
... 
    override func viewDidLoad() { 
     super.viewDidLoad() 

     AddPlayerViewController.delegate = self 
... 
    func returnPlayerInfo(playerName : String, playerType : Player.Type) { 
     mGame.addPlayer(playerName, newPlayerClass: playerType, fKActivity: self) 
} 

Questo funziona molto bene. Vedi qualche problema con la mia implementazione?

+0

Hai detto di essere stato confuso dalla risposta usando i delegati. E tu usi anche il delegato nella tua risposta. Cosa volevi dire che eri confuso? –

+0

È inoltre necessario assicurarsi che la variabile delegata sia debole per impedire un ciclo di memoria 'delegato var debole statico: ReturnPlayerInfoDelegate?' –

0

Spero che questo vi aiuterà a

Questo il secondo controller da cui si desidera per restituire dati a spinta. SecondView.swift

@objc protocol returnDataProtocol { 
    func returnStringData(myData: String) 
} 




class SecondView: UIViewController { 


     weak var delegate: returnStringData? 


     @IBAction func readyButtonPressed(sender: AnyObject) { 

     // Do what you want here 

     delegate?.returnStringData("Euro/Dollar etc....") 
     // this function is exist in first view controller 

     } 
    } 

prima vista ViewController firstView.swift

class firstView: UIViewController, returnDataProtocol { 
    // this function will call to second view. You can use here push method, if you are using navigation controller. 
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
     if segue.identifier == "mySegue" { // your identifier here 
      let controller = segue.destinationViewController as! MyPopOverController 
      controller.delegate = self 
     } 
    } 

    // here you will get return value from second view controller class 

    func returnStringData(myData: String){ 
      print(myData) 
     } 

}