Подтвердить что ты не робот

Передача данных с помощью разматывания

Я создал два контроллера вида. Я создал segue от первого до второго, чтобы передать данные. Теперь я хочу передать данные с второго контроллера представления на первый. Я прошел множество подобных вопросов, и я не в состоянии реализовать их, поскольку мне не хватает знаний о том, как работает раскрутка.

ViewController.swift

class ViewController: UIViewController
{   
    var dataRecieved: String?
    @IBOutlet weak var labelOne: UILabel!
    @IBAction func buttonOne(sender: UIButton)
    {
        performSegueWithIdentifier("viewNext", sender: self)
    }
    override func prepareForSegue(segue: (UIStoryboardSegue!), sender: AnyObject!)
    {

        var svc: viewControllerB = segue.destinationViewController as! viewControllerB
        svc.dataPassed = labelOne.text
    }
}

Это передаст данные на dataPassed в поле зрения контроллера viewControllerB. Скажем, теперь я хочу передать некоторые данные из viewControllerB в dataRecieved в ViewController. Как я могу сделать это, только разматывая segue, а не используя делегат. Я совершенно новый, быстрый, буду благодарен за подробное объяснение.

4b9b3361

Ответ 1

Øyvind Hauge избил меня к тому же методу решения, но, как я уже начал с более подробного ответа, я также добавлю его.


Предположим, что ваши два контроллера представления названы следующим образом:

  • Мастер/точка входа: ViewController (vcA)
  • Вторичный вид: ViewControllerB (vcB)

Вы установили segue из (vcA) -> (vcB), как вы это сделали в примере

/* in ViewController.swift */   

// ...

// segue ViewController -> ViewControllerB
override func prepareForSegue(segue: (UIStoryboardSegue!), sender: AnyObject!)
{
    if segue.identifier == "viewNext" {
        let viewControllerB = segue.destinationViewController as! ViewControllerB
        viewControllerB.dataPassed = labelOne.text
    }
}

Несколько сложный шаг следующий заключается в том, что с помощью этого метода сегмент, используемый для передачи данных от (vcB) до (vcA), также добавляется к источнику (vcA) в качестве метода @IBAction (а не, как и следовало ожидать, добавляется к источнику (vcB)).

/* in ViewController.swift */   

// ...

// segue ViewControllerB -> ViewController
@IBAction func unwindToThisView(sender: UIStoryboardSegue) {
    if let sourceViewController = sender.sourceViewController as? ViewControllerB {
        dataRecieved = sourceViewController.dataPassed
    }
}

После этого подключите, скажем, кнопку (vcB) к этому оператору разматывания в (vcA) с помощью руководства Exit segue в (vcB):

введите описание изображения здесь

Ниже приведен полный пример прохождения текста от (vcA) до (vcB); (возможно), изменяя этот текст через UITextField, вернув (возможно) измененный текст в (vcA).


(vcA) источник:

/* ViewController.swift: Initial view controller */
import UIKit

class ViewController: UIViewController {

    var dataRecieved: String? {
        willSet {
            labelOne.text = newValue
        }
    }
    @IBOutlet weak var labelOne: UILabel!

    @IBAction func buttonOne(sender: UIButton) {
        performSegueWithIdentifier("viewNext", sender: self)
    }

    // set default labelOne text
    override func viewDidLoad() {
        super.viewDidLoad()

        labelOne.text = "Default passed data"
    }

    // segue ViewController -> ViewControllerB
    override func prepareForSegue(segue: (UIStoryboardSegue!), sender: AnyObject!)
    {
        if segue.identifier == "viewNext" {
            let viewControllerB = segue.destinationViewController as! ViewControllerB
            viewControllerB.dataPassed = labelOne.text
        }
    }

    // segue ViewControllerB -> ViewController
    @IBAction func unwindToThisView(sender: UIStoryboardSegue) {
        if let sourceViewController = sender.sourceViewController as? ViewControllerB {
            dataRecieved = sourceViewController.dataPassed
        }
    }
}

(vcB) source (обратите внимание, что делегат UITextFieldDelegate здесь используется только для "локально", изменяющего значение свойства dataPassed, которое будет возвращено в (vcA) и присвоено свойству dataRecieved последняя)

/* ViewControllerB.swift */
import UIKit

class ViewControllerB: UIViewController, UITextFieldDelegate {

    var dataPassed : String?
    @IBOutlet weak var textField: UITextField!

    // set default textField text to the data passed from previous view.
    override func viewDidLoad() {
        super.viewDidLoad()

        textField.text = dataPassed

        // Handle the user input in the text field through delegate callbacks
        textField.delegate = self
    }


    // UITextFieldDelegate
    func textFieldShouldReturn(textField: UITextField) -> Bool {
        // User finished typing (hit return): hide the keyboard.
        textField.resignFirstResponder()
        return true
    }

    func textFieldDidEndEditing(textField: UITextField) {
        dataPassed = textField.text
    }
}

Пример выполнения:

введите описание изображения здесь

Ответ 2

Вот как я это сделаю:

  • Создайте розетку в виде контроллера 1, например:

    @IBAction func unwindToViewController1(segue: UIStoryboardSegue) {
    
       let foo = segue.sourceViewController.foo
    
       // TODO: Use foo in view controller 1
    }
    
  • Подключите контроллер 2 просмотра (vc, который вы отключаете), как показано ниже. Перетащите из желтого круга в vc2 в "Выход". Появится сообщение IBAction из контроллера 1. Выберите его. введите описание изображения здесь

  • Теперь, когда вы отключаетесь от контроллера 2, будет вызван метод unwindToViewController1: в представлении контроллера 1.

  • Здесь вы получите требуемое свойство из контроллера просмотра 2. Обратите внимание, что вам нужно отнести segue.sourceViewController к своему подклассу настраиваемого представления, чтобы получить правильное свойство.