Передача данных с контроллеров просмотра Xcode

Пару недель назад я задал этот вопрос и получил очень подробное объяснение. Теперь я хотел бы передать данные обратно в первый ViewController, но я продолжаю застревать, используя тот же метод. У меня есть модальный первый VC ко второму, где я хотел бы отредактировать массив строк, который будет показан на первом представлении снова. Таким образом, на моем первом представлении у меня есть массив данных, который должен быть передан второму, так что поля редактирования отображают текущую информацию, после которой пользователь должен иметь возможность редактировать содержимое массива и передавать эти данные в первый, где он отображается на этикетках. Я использую Свифт.

Мой код:

(в ViewController.swift :)

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

(в SecondViewController.swift :)

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

спасибо

Ответ 1

Вам нужно использовать делегат. Ниже приведен пример использования делегата в Swift.

На первом ViewController установите делегат при загрузке второго VC:

Например, если вы используете редактор раскадровки:

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

Напишите протокол и определите функцию, чтобы записать значения обратно

Например, создайте файл под названием "Protocol.swift" и напишите что-нибудь вроде этого:

protocol writeValueBackDelegate {
    func writeValueBack(value: String)
}

Добавьте функцию в свой FirstViewController

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

И вашему ViewControllerClass

class ViewController: UIViewController, writeValueBackDelegate

Вышеуказанная строка не будет работать, если вы не внедрили все методы в ViewController, определенные в файле протокола.

Перейдите к контроллеру второго представления и добавьте делегат здесь:

class SecondViewController: ViewController {

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

На вашем втором контроллере просмотра вы теперь можете использовать это, чтобы вызвать func в первом View Controller данные прохода.

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

Ответ 2

Я смущен ответом, используя делегатов, потому что это кажется мне бесполезно сложным. Вот что я сделал, чтобы открыть диалоговое окно Add Player в моей карточной игре и передать результаты обратно контроллеру вызова.

Добавить делегатский протокол (в моем случае в файле Extensions/Protocols)

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

Затем я добавил ссылку (как класс var) на делегат в CALLED View Controller. Обратите внимание, что это не требовало моего подкласса моего вызывающего абонента или добавления протокола к вызываемому контроллеру View:

class AddPlayerViewController : UIViewController {
     static var delegate : ReturnPlayerInfoDelegate!

и вызвал делегата в моем обработчике кнопок Ok:

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

Теперь я внедрил делегата в 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)
}

Это работает очень хорошо. Вы видите какие-либо проблемы с моей реализацией?

Ответ 3

Надеюсь, что это поможет вам

Это второй контроллер, из которого вы хотите вернуть данные. 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 

        }
    }

Первый вид 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)
       }

}