Представить контроллер предупреждений из ячейки табличного представления на нескольких контроллерах представления - PullRequest
1 голос
/ 17 октября 2019

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

https://stackoverflow.com/a/49199783/6724161

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

Как представить контроллер оповещений на любом контроллере представлений при нажатии кнопки в ячейке табличного представления?

Ответы [ 3 ]

1 голос
/ 17 октября 2019

Вы можете использовать уведомления, как указано в комментариях, но я бы сделал кое-что еще.

1. В вашем пользовательском классе я бы добавил свойство с именем parentVC типа UIViewController:

class YourTableViewCell: UITableViewCell {

    var parentVC: UIViewController!

    ...

}

2. Затем, когда вы удаляете ячейку из очереди, я бы установил для parentVC ячейки self, например, так:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell: UITableViewCell! = tableView.dequeueReusableCell(withIdentifier: "YourCellIdentifier") as! YourTableViewCell
    //`self` is the view controller that the cell's table view is held in
    cell.parentVC = self
    return cell
}

3. Наконец, когда ваша пользовательская ячейканажата кнопка, просто представьте контроллер оповещений из parentVC:

class YourTableViewCell: UITableViewCell {

    var parentVC: UIViewController!

    @IBAction func customButtonPressed(_ sender: Any) {
        let alertController = UIAlertController(title: "Your alert title.", message: "Your alert message.", preferredStyle: .alert)
        parentVC.present(alertController, animated: true, completion: nil)
    }

    ...

}

Еще один вариант (в соответствии с предложением rmaddy)

Вы можете просто изменить кнопку вваш UITableViewCell для рекурсивной проверки следующего респондента, пока он не будет иметь тип UIViewController.

Сначала добавьте следующее расширение к UIView. Это найдет родительский контроллер представления UIView:

extension UIView {
    var parentViewController: UIViewController? {
        var parentResponder: UIResponder? = self
        while parentResponder != nil {
            parentResponder = parentResponder!.next
            if let viewController = parentResponder as? UIViewController {
                return viewController
            }
        }
        return nil
    }
}

Вы можете просто изменить кнопку в вашем UITableViewCell, чтобы рекурсивно проверять следующий респондент, пока он не будет иметь тип UIViewController. Как только вы найдете это UIViewController, вы можете предоставить ему UIAlertController или любой другой контроллер представления:

Источник: Если получить представление, как мне получить его viewController?

Когда вы найдете это UIViewController, вы можете представить его UIAlertController или любым другим контроллером вида:

class YourTableViewCell: UITableViewCell {

    ...

    @IBAction func customButtonPressed(_ sender: Any) {
        let alertController = UIAlertController(title: "Your alert title.", message: "Your alert message.", preferredStyle: .alert)

        guard let parentVC = self.parentViewController else { return }   
        parentVC.present(alertController, animated: true, completion: nil)
    }

    ...

}
0 голосов
/ 17 октября 2019

Вы можете решить свою проблему с помощью шаблона Notification.

Во-первых, я настоятельно рекомендую построить диаграмму уведомлений с расширением Notification.Name для ваших предупреждений.

extension Notification.Name {
    static let notificationForAlertingStuff = Notification.Name("isAlertReallyAlert")
}

Затем создайте уведомление наблюдателя для оповещения.

override func viewDidLoad() {
   NotificationCenter.default.addObserver(self, selector: #selector(onDidReceiveData(_:)), name: Notification.Name("isAlertReallyAlert"), object: nil)
}

Создайте свою собственную функцию обработчика уведомлений.

@objc private func onDidReceiveData(_ notification: NSNotification){
        print("notification has fired. user info => \(notification.userInfo) ")

      // present alert
    }

Я думаю, что вы должны расширить UIViewController и добавить простую функцию оповещения с помощьюполучение title и description параметров. На данный момент есть только распечатка информации из Notification.

Затем, когда вы запускаете любое Уведомление, используйте эту функцию при нажатии кнопки или щелчке строки.

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        var alertData = ["title": "Alert Title", "description": "Alert Description"]

        NotificationCenter.default.post(name: Notification.Name("isAlertReallyAlert"), object: self, userInfo: alertData)
    }

Так что, возможно, вы можете указать и добавитьфункция для информации пользователя для подготовки любого оповещения.

Наконец, вот расширение для UIViewController для использования UIAlertController efficiently.

extension UIViewController{


    func shotAlert(title:String, description:String){
        // Create Alert Controller

    }

}

// ХОРОШИЙ ПУНКТ:

Предположим, что ваши контроллеры вида A, B and C живут в стеке UINavigationController, как A -> B -> C, поэтому, если вы добавите наблюдателя в контроллер, вы можете запустить любое уведомление из C, как вы правильно описали Notification.Name.

0 голосов
/ 17 октября 2019

Вы можете представить, используя свойство окна AppDelegates.

let alert = UIAlertController(title: "title", message: "message", preferredStyle: .alert)
let action = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alert.addAction(action)
UIApplication.shared.keyWindow?.rootViewController?.present(alert, animated: true, completion: nil)

Лучше у вас есть проверка, основанная на типе вашего приложения rootViewController, чтобы избежать проблем. Например,

  • , если rootViewController является навигационным контроллером, вы можете взять верхний viewController навигационного контроллера и представить предупреждение.

  • , если rootViewController - это UIViewController, вы можете представить его непосредственно из rootViewController.

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