Передача данных с контроллеров просмотра 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)
}
}