Невозможно переместить alertController в расширение UIViewController, если для этого требуется функция обработчика - PullRequest
1 голос
/ 14 апреля 2019

Во всей моей программе я вызываю UIAlertControllers несколько раз. Чтобы упростить чтение, я смог успешно выделить AlertController, если он имеет только действие «ОК» с nil в качестве обработчика.

Я изо всех сил пытаюсь сделать то же самое, если я хочу передать функцию, которую я хочу связать, как UIAlertAction. func showOKCancelAlertController не компилируется

showOKAlertController(title: "Network Error", message: "Unable to download photos") //This is an example of how I call Alert Controller throughout my code.

extension UIViewController {
    func showOKAlertController(title: String, message: String){
        let myAlertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
        myAlertController.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
        present(myAlertController, animated: true)
    }

    func showOKCancelAlertController(title: String, message: String, okFunction: UIAlertAction ){
        let myAlertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
        myAlertController.addAction(UIAlertAction(title: "OK", style: .default, handler: okFunction))
        myAlertController.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil))
        present(myAlertController, animated: true)
    }
} 

Ответы [ 4 ]

1 голос
/ 14 апреля 2019

Усовершенствуйте свой код на моем пути

Это гибкий инструмент для обработки обработчика завершения

extension UIViewController {
    func showOKAlertController(title: String, message: String? = nil, okCompletion: @escaping (() -> ()) = {}, presentCompletion: @escaping (() -> ()) = {}) {
        let myAlertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
        let okAction = UIAlertAction(title: "OK", style: .default) { (action: UIAlertAction) in
            okCompletion()
        }
        myAlertController.addAction(okAction)
        DispatchQueue.main.async {
            self.present(alertController, animated: true) {
                presentCompletion()
            }
        }
    }

    func showOKCancelAlertController(title: String, message: String? = nil, okCompletion: @escaping (() -> ()) = {}, cancelCompletion: @escaping (() -> ()) = {}, presentCompletion: @escaping (() -> ()) = {}) {
        let myAlertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
        let okAction = UIAlertAction(title: "OK", style: .default) { (action: UIAlertAction) in
            okCompletion()
        }
        let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (cancel: UIAlertAction) in
            cancelCompletion()
        }
        myAlertController.addAction(okAction)
        myAlertController.addAction(cancelAction)
        DispatchQueue.main.async {
            self.present(alertController, animated: true) {
                presentCompletion()
            }
        }
    }
}

showOKAlertController(title: "message")

или

showOKAlertController(title: "message", message: "message")

или

showOKCancelAlertController(title: "message", message: nil, okCompletion: {
    // ok completion handling
}) {
    // present completion handling
}

или вы можете сослаться на полезное из моего gist

1 голос
/ 14 апреля 2019

Может быть

extension UIViewController { 
    func showOKAlertController(title: String, message: String,ok:@escaping(() -> ())) {
        let myAlertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
        myAlertController.addAction(UIAlertAction(title: "ok", style: .default, handler: { (al) in
            ok()
        }))
        myAlertController.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil))
        present(myAlertController, animated: true)
    }
}

showOKAlertController(title: "This is title", message: "this is message") {
   print("ok")
}
1 голос
/ 14 апреля 2019

Очевидно, что ошибка, с которой вы сталкиваетесь:

Невозможно преобразовать значение типа 'UIAlertAction' в ожидаемый тип аргумента '((UIAlertAction) -> Void)?'

это потому, что okFunction параметр типа UIAlertAction, это неверная часть.Вы должны позволить okFunction иметь тип ((UIAlertAction) -> Void)? вместо:

func showOKCancelAlertController(title: String, message: String, okFunction: ((UIAlertAction) -> Void)?) {
    let myAlertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
    myAlertController.addAction(UIAlertAction(title: "OK", style: .default, handler: okFunction))
    myAlertController.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil))
    present(myAlertController, animated: true)
}

, и это потому, что подпись UIAlertAction init:

init(title: String?, style: UIAlertAction.Style, handler: ((UIAlertAction) -> Void)? = nil),

параметр handler ожидает ((UIAlertAction) -> Void)?.

Таким образом, вы называете его следующим образом:

showOKCancelAlertController(title: "title", message: "message") { _ in
    print("here is what to do when tapping the OK button")
}

Кроме того, если для кнопки ОК нет действия, чтоВы могли бы дать значение nil по умолчанию для параметра okFunction:

func showOKCancelAlertController(title: String, message: String, okFunction: ((UIAlertAction) -> Void)? = nil)

и назвать его как:

showOKCancelAlertController(title: "title", message: "message")

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

func showAlertController(title: String, message: String, okFunction: ((UIAlertAction) -> Void)? = nil) {
    let myAlertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
    myAlertController.addAction(UIAlertAction(title: "OK", style: .default, handler: okFunction))
    if let okFun = okFunction {
        myAlertController.addAction(UIAlertAction(title: "Cancel", style: .default, handler: okFun))
    }

    present(myAlertController, animated: true)
}

Если вы хотите показать его одной кнопкой:

showAlertController(title: "title", message: "message")

и для двух кнопок:

showAlertController(title: "title", message: "message") { _ in
    // ...
}
1 голос
/ 14 апреля 2019

Ожидаемый тип обработчика: ((UIAlertAction) -> Swift.Void)?, а не UIAlertAction

Обновите код до

func showOKCancelAlertController(title: String, message: String, okFunction: ((UIAlertAction) -> Swift.Void)? ){
     let myAlertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
     myAlertController.addAction(UIAlertAction(title: "OK", style: .default, handler: okFunction))
     myAlertController.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil))
     present(myAlertController, animated: true)
}
...