Передача данных между ViewControllers зависит от тега UIButton - PullRequest
0 голосов
/ 05 декабря 2018

У меня UITableView, и я передаю выделенный Item от одного UIViewController к другому.Для этого у меня есть массив Item объектов.

var array = [Item]()

для выполнения перехода Я передаю sender параметр действия buttonPressed как sender метода performSegue.

@IBAction func buttonPressed(_ sender: UIButton) {
    performSegue(withIdentifier: "identifier", sender: sender)
}

Эта кнопка находится внутри UITableViewCell и имеет тэг, равный indexPath.row, который я установил в TableView cellForRowAt метод источника данных:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    ...
    cell.myButton.tag = indexPath.row
    ...
}

Затем в ViewController prepare метод Idowncast sender как UIButton, а затем я назначаю переменную selectedItem в целевом ViewController как Item из array с button.tag в качестве индекса.

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "identifier" {
        let button = sender as! UIButton
        let destinationVC = segue.destination as! ViewController2
        destinationVC.selectedItem = array[button.tag]
    }
}

Q: Это работает просто отлично, я использую это в течение длительного времени, но у меня есть ощущение, что это не правильное решение.Есть ли что-нибудь лучше?

Ответы [ 2 ]

0 голосов
/ 05 декабря 2018

Здесь я предпочитаю использовать шаблон делегата.

В этом подходе контроллер представления делает себя делегатом каждой ячейки представления таблицы, которую он создает.Он передает Item в клетку.При нажатии кнопки в ячейке ячейка отправляет Item обратно в контроллер представления.Таким образом, контроллер представления знает, какой Item был выбран, и должен быть отправлен следующему контроллеру представления.

Для реализации, начните с объявления переменной в ячейке табличного представления для хранения Item:

weak var item: Item?

В вашем контроллере представления передайте элемент в ячейку:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    //...
    cell.item = array[indexPath.row]
    //...
}

Затем объявите протокол делегата:

protocol ItemSelectionDelegate {
    func itemSelected(_ item: Item)
}

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

weak var delegate: ItemSelectionDelegate?

Сделайте так, чтобы кнопка в ячейке табличного представления вызывала делегата при нажатии, передавая ему элемент:

@IBAction func buttonPressed(_ sender: UIButton) {
    if let item = item {
        delegate?.itemSelected(item)
    }
}

Теперь сделайтеКонтроллер представления соответствует этому протоколу:

class MyViewController: UIViewController, ..., ItemSelectionDelegate {

    func itemSelected(_ item: Item) {
        //...
    }
}

Убедитесь, что контроллер представления установлен как делегат каждой ячейки:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    //...
    cell.item = array[indexPath.row]
    cell.delegate = self
    //...
}

Вызовите свой переход, но вместо этого передайте Itemкнопки:

class MyViewController: UIViewController, ..., ItemSelectionDelegate {

    func itemSelected(_ item: Item) {
        performSegue(withIdentifier: "identifier", sender: item)
    }
}

Теперь передайте это следующему контроллеру представления:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "identifier" {
        let destinationVC = segue.destination as! ViewController2
        destinationVC.selectedItem = sender as? Item
    }
}

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

0 голосов
/ 05 декабря 2018

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

    if segue.identifier == "identifier" {
        guard let destinationVC = segue.destination as? ViewController2 else { return }
        guard let selectedIndexPath = self.tableView.indexPathForSelectedRow else { return }
        destinationVC.selectedItem = selectedIndexPath.row 
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...