Представление UIAlertController из UITableViewCell

Я пытаюсь добавить оповещения в пользовательский UITableViewCell для представления UIAlertView Мне нужно вызвать presentViewController из UIViewController. Однако я не знаю, как получить доступ к текущему экземпляру UIViewController из класса UITableViewCell. Следующий код - это моя попытка сделать это с расширением.

Я получаю эту ошибку

Выражение разрешено для неиспользуемой функции.

extension UIViewController
{

    class func alertReminden(timeInterval: Int)
    {
        var refreshAlert = UIAlertController(title: "Refresh", message: "All data will be lost.", preferredStyle: UIAlertControllerStyle.Alert)

        refreshAlert.addAction(UIAlertAction(title: "Ok", style: .Default, handler: { (action: UIAlertAction!) in
            Alarm.createReminder("Catch the Bus",
                timeInterval: NSDate(timeIntervalSinceNow: Double(timeInterval * 60)))
        }))

        refreshAlert.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: { (action: UIAlertAction!) in
            println("Handle Cancel Logic here")
        }))

        UIViewController.presentViewController(refreshAlert)


    }
}

class CustomRouteViewCell: UITableViewCell {

Ответ 1

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

extension UIView {
var parentViewController: UIViewController? {
    var parentResponder: UIResponder? = self
    while parentResponder != nil {
        parentResponder = parentResponder!.nextResponder()
        if parentResponder is UIViewController {
            return parentResponder as! UIViewController!
        }
    }
    return nil
}
}

Или используйте rootViewController для представления:

UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(refreshAlert, animated: true, completion: nil)

Обновление Swift 4.2

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

Или используйте rootViewController для представления:

UIApplication.shared.keyWindow?.rootViewController?.present(alertVC, animated: true, completion: nil)

Ответ 2

Попробуйте заменить эту строку кода:

Swift 2

UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(refreshAlert, animated: true, completion: nil)

Swift 3

UIApplication.shared.keyWindow?.rootViewController?.present(refreshAlert, animated: true, completion: nil)

Ответ 3

Другой способ сделать это - объявить протокол и свойство делегата в классе ячеек таблицы, установить контроллер как делегат ячеек и реализовать протокол в контроллере, который может представить контроллер представления предупреждений.

Ответ 4

Левское решение сработало для меня. Я использовал его для представления AlertView из ячейки пользовательской коллекции.

Обновление для Swift 3.0:

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

Надеюсь, что это поможет.

Ответ 5

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

protocol alerts: class{

    func presentAlert(title:String, message:String)

}

Затем в вашем TableViewCell вы создадите что-то вроде:

var alertsDelegate : alerts? 

//And whenever you need to present a message call something inside the cell like:

alertsDelegate?.presentAlert(title:"Your title", message:"Your message")

Затем в вашем viewController сначала установите viewController как оповещения.

class yourClassName : ViewController, alerts {

    //And add the functions of the protocol
    func presentAlert(title:String, message:String){
        //This is the function that'll be called from the cell
        //Here you can personalize how the alert will be displayed

    }
}

Во-вторых, установите делегат для ячейки в методе cellForRowAt

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "yourIdentifier") as! yourCellClass

    cell.alertsDelegate = self

}

И так же, как это, вы можете создавать несколько функций, которые адаптируют ваши потребности по отношению к общению с вашим контроллером viewController или viewControllers.

Ответ 6

Должны быть объявлены протокол и их свойство делегата в CustomTableViewCell Class and called these properties at the place of UIAlertViewController, и реализовать эти свойства протокола в UIViewController.