2014-08-27 15 views
13

Kilka tygodni temu zadałem pytanie this i otrzymałem bardzo szczegółowe wyjaśnienie. Teraz chciałbym przekazać dane z powrotem do pierwszego ViewController, ale nadal utknąć przy użyciu tej samej metody. Mam modalny pierwszy VC do drugiego, w którym chciałbym edytować tablicę łańcuchów, które będą ponownie wyświetlane w pierwszym widoku. Tak więc w moim pierwszym widoku mam szereg danych, które powinny być przekazane do drugiego, więc pola edycji pokazują bieżące informacje, po których użytkownik musi mieć możliwość edycji zawartości tablicy i przekazania tych danych do pierwszego miejsca, gdzie jest pokazany na etykietach. Używam Swift.Przekazywanie danych z kontrolerów widoku Xcode

Mój kod:

(w ViewController.swift :)

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

(w SecondViewController.swift :)

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

Dziękuję

+0

Gdzie jest kod? – Raptor

+0

Przepraszam, zaktualizowałem mój OP –

Odpowiedz

36

Musisz użyć delegat. Oto przykład użycia delegata w Swift.

Na pierwszym ViewController, ustawić delegata podczas ładowania drugiego VC:

Na przykład, jeśli używasz edytora Storyboard:

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

Napisz protokół i zdefiniować func napisać Ci wartości z powrotem

na przykład utworzyć plik o nazwie „Protocol.swift” i napisać coś takiego:

protocol writeValueBackDelegate { 
    func writeValueBack(value: String) 
} 

Dodaj funkcję do FirstViewController

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

I do ViewControllerClass

class ViewController: UIViewController, writeValueBackDelegate 

Powyższa linia nie będzie działać, jeśli nie zostały zaimplementowane wszystkie metody w ViewController że zdefiniowanych w protokole plik.

idź do drugiego widoku kontrolera i dodaj delegata tutaj:

class SecondViewController: ViewController { 

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

Na drugim widoku kontrolera, można to wykorzystać, aby wywołać func w pierwszym View Controller e dane Pass.

delegate?.writeValueBack("That is a value") 
+0

Musisz również wskazać, że twój pierwszy kontroler widoku implementuje protokół: 'class ViewController: UIViewController, writeValueBackDelegate {' – vacawama

+0

Dzięki, zapomniałem tego. Edytuję mój wątek – derdida

+0

Czy nie możemy użyć tutaj zamknięć, aby osiągnąć to samo? – Satyam

0

Jestem zdezorientowany przez odpowiedź, używając delegatów, ponieważ wydaje mi się niepotrzebnie skomplikowana. Oto, co zrobiłem, aby otworzyć okno dialogowe Dodaj odtwarzacz w mojej grze karcianej i przekazać wyniki z powrotem do kontrolera widoku połączeń.

protokół dodawania delegat (w moim przypadku w moim Rozszerzenia/pliku Protokoły)

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

Potem dodałam mój odniesienia (jako klasa VAR) do delegata w nazywa View Controller.Uwaga ta nie wymaga mój instacji mojego rozmówcę lub dodanie protokołu do mojego nazwie View Controller:

class AddPlayerViewController : UIViewController { 
    static var delegate : ReturnPlayerInfoDelegate! 

i nazwał delegata w moim Ok obsługi przycisku:

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

Teraz realizowany delegata w 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) 
} 

To działa bardzo ładnie. Czy widzisz jakieś problemy z moją implementacją?

+0

Powiedziałeś, że jesteś zdezorientowany przez odpowiedź, używając delegatów. Używasz także delegata w swojej odpowiedzi. Co miałeś na myśli, że byłeś zdezorientowany? –

+0

Należy również upewnić się, że zmienna delegata jest słaba, aby zapobiec cyklowi pamięci "statyczne słabe delegat var: ReturnPlayerInfoDelegate?" –

0

nadzieję, że pomoże Ci

ten drugi kontroler skąd chcesz powrócić danych wciśnięty. 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 

     } 
    } 

Pierwszy widok 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) 
     } 

} 
Powiązane problemy