я не могу передавать данные между viewcontrollers через протоколы - PullRequest
0 голосов
/ 13 января 2019

Просмотр контроллера A

class ViewController: UIViewController {

    var delegate: server?

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func ok(_ sender: Any) {
        delegate?.datum(data: "sd")
        performSegue(withIdentifier: "goingB", sender: self)
    }

}

Просмотр контроллера B

protocol server {
    func datum(data: String)
}

class ViewControllerB: UIViewController, server {

    @IBOutlet weak var label: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()    
    }

    func datum(data: String) {
        self.label.text = data
        print(data)
    }

}

Мне нужно передать данные через контроллеры представления, но я не могу их передать, однако я знаю, что мы можем передавать данные через протоколы, но в любом случае я получаю ошибку при попытке запустить программу

Ответы [ 2 ]

0 голосов
/ 13 января 2019

Самое простое - установить свойство непосредственно при подготовке.

Однако, если вы хотите использовать делегат, вы можете. Ваша проблема в том, что вы смешали A и B. То, как вы это написали, когда вы вызываете делегат? .Datum, делегат не определен, и мы не можем получить доступ к данным. Что ты хочешь делать ? Перейдите от A к B, а когда в B, обновите метку в B данными, полученными от A.
Здесь просто чтобы показать, как использовать (но явно слишком сложный по сравнению с прямым назначением).

protocol Server {
    func datum() -> String
}

class ViewControllerB: UIViewController {

    @IBOutlet weak var label: UILabel!

    var delegate: Server?

    override func viewDidLoad() {
        super.viewDidLoad()
        let data = delegate?.datum()
        self.label.text = data
    }


}

class ViewControllerA: UIViewController, Server {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    var data = "sd"

    func datum() -> String {
        return data
    }

    @IBAction func ok(_ sender: Any) {
        performSegue(withIdentifier: "goingB", sender: self)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let destVC = segue.destination as? ViewControllerB {
            destVC.delegate = self
        }
    }
}
0 голосов
/ 13 января 2019

Если вам нужно передать данные с одного контроллера представления на другой, и вы используете segue для представления нового контроллера представления, вы можете просто переопределить prepare(for:sender:), нет необходимости использовать делегаты. Здесь вы можете получить ссылку на контроллер, который будет представлен, и вы можете назначить его переменную.

Итак, сначала создайте переменную во втором контроллере представления и объявите, что если вы присваиваете ей новое значение, это изменит текст вашей метки

class ViewControllerB: UIViewController {

    @IBOutlet weak var label: UILabel!

    var variable: String? {
        didSet {
            label.text = variable
        }
    }
}

Теперь в первом представлении контроллер переопределяет prepare(for:sender:), и, если segue - segue, который вы выполнили, понизьте целевой контроллер вида и назначьте его переменную

class ViewController: UIViewController {

    @IBAction func ok(_ sender: Any) {
        performSegue(withIdentifier: "goingB", sender: self)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "goingB" {
            let destinationVC = segue.destination as! ViewControllerB
            destinationVC.variable = "sd"
        }
    }

}

В любом случае, если вы хотите использовать свой код с делегатом, вы должны установить делегат первого контроллера представления в качестве контроллера второго представления, который будет представлен. Для этой цели вы также можете использовать prepare(for:sender:), где вы можете получить ссылку для назначения segue, а затем вы можете вызвать свой метод для делегата

class ViewController: UIViewController {

    var delegate: server?

    @IBAction func ok(_ sender: Any) {
        performSegue(withIdentifier: "goingB", sender: self)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "goingB" {
            let destinationVC = segue.destination as! ViewControllerB
            delegate = destinationVC
            delegate?.datum(data: "sd")
        }
    }

}

Примечания:

  • Название протокола с большой заглавной буквой Server, и мы говорим о делегатах, добавьте слово делегата: ServerDelegate
  • Протокол ограничения для только классов
  • Сделайте тогда свою переменную делегата weak

protocol ServerDelegate: class {
    func datum(data: String)
}

...

weak var delegate: ServerDelegate?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...