Делегирование для передачи данных обратно из модально представленного контроллера представления - PullRequest
1 голос
/ 14 марта 2020

Допустим, у нас есть два контроллера представления, родительский элемент с меткой и модально представленный дочерний элемент с табличным представлением. Как передать выбор пользователя в табличном представлении родителю с помощью делегирования?

ViewController1:

   var delegate: vc2delegate?

   override func viewDidLoad {
        super.viewDidLoad()
        let label.text = ""
   }

ViewController2:

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
           return 5
       }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! Cell
            let selections = ["1", "2", "3", "4", "5"]
            cell.selections.text = selections[indexPath.row]
            return cell
       }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if let cell = tableView.cellForRow(at: indexPath) as? Cell {
            cell.didSelect(indexPath: indexPath as NSIndexPath)

            }

        dismiss(animated: true, completion: nil)
        } 
   //wherever end of class is

   protocol vc2delegate {
      // delegate functions here
   }

Есть ли у меня правильный подход? Я никогда не разбирался в этом паттерне, и я думаю, что для меня важно научиться за iOS. Другим хитрым предостережением может быть то, что viewDidLoad () не вызывается, когда вы закрываете модальный контроллер представления.

Ответы [ 2 ]

3 голосов
/ 14 марта 2020

Взгляните на жизненный цикл UIViewController docs : ViewDidLoad вызывается только один раз.

Существует множество руководств о том, как это сделать, просто выполните быстрый поиск. Вам нужно будет обновить логи dataSource c, поскольку я добавил быстрый строковый массив, и у вас, скорее всего, будет что-то более сложное, но идея все та же.

Кстати, я использовал ваше соглашение об именах vc1 / vc2, но я надеюсь, что у вас есть более значимые имена для ваших контроллеров.

В вашем коде у вас неправильный делегат V C. Вот краткий пример того, как он должен выглядеть:

class VC1: UIViewController {

    let textLabel = UILabel()

    // whenever you're presenting the vc2
    func presentVC2() {
        var vc2 = VC2()
        vc2.delegate = self
        self.present(vc2, animated: true, completion: nil)
    }
}

extension VC1: VC2Delegate {
    func updateLabel(withText text: String) {
        self.textLabel.text = text
    }
}


protocol VC2Delegate: class {
    func updateLabel(withText text: String)
}

class VC2: UIViewController {
    weak var delegate: VC2Delegate?
    let dataSource = ["string 1", "tring 2"]
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let string = dataSource[indexPath.row]
        self.delegate?.updateLabel(withText: string)
        dismiss(animated: true, completion: nil)
    }
}
0 голосов
/ 14 марта 2020

Вы можете использовать функцию callback также для обновления метки из таблицы:

1) Объявление функции обратного вызова в VC2 :

var callback:((String) -> Void)?

2) Вызовите эту функцию в табличном методе CellForRowAt вашего просмотра в VC2 :

let dataSource = ["string 1", "tring 2"]

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
      let string = dataSource[indexPath.row]  
      var cell = tableView.dequeueReusableCell(withIdentifier: "yourCell") as! YourCell

     //here you can call callback function & pass string to VC1
     cell.callback?(dataSource[indexPath.row])
}

3) Теперь вы можете вызвать обратный вызов в VC1 в любом месте, где вы звоните своему VC2:

class VC1: UIViewController {

    let textLabel = UILabel()

    //I'm calling this(presentVC2()) function on ViewDidLoad you can call anywhere you want
    func viewDidLoad() {
        super.viewDidLoad()
        presentVC2()
    }

    // whenever you're presenting the vc2
    func presentVC2() {
        var vc2 = VC2()
        vc2.callback = { text in
            self.textLabel.text = text
        }
        self.present(vc2, animated: true, completion: nil)
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...