UIAlertController не отображается сразу - PullRequest
1 голос
/ 26 июня 2019

Я новичок в программировании на Swift, но не могу найти ответ на мою проблему, которая ...

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

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

Я искал Stackoverflow и перечитал документацию Apple для разработчиков для UIAlertController и UIAlertAction, но не могу понять, почему код не останавливается, пока пользователь не ответит.

Я попытался поставитьUIAlertController кодирует в своей собственной функции, но предупреждение все еще отображается не по порядку.Я думаю, может быть, должна быть задержка, чтобы позволить Alert рисовать до выполнения следующей строки кода (?).

@IBAction func buttonTapped(_ sender: Any) {

    let alert = UIAlertController(title: "Ouch", message: "You didn't have to press me so hard!", preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "Sorry", style: .default, handler: { _ in
        self.handleAlert()
    }))
    self.present(alert, animated: true, completion: nil)

    print("Should be printed last!")
}

func handleAlert() {
    print("UIAlertAction handler printed me")
}

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

Обработчик UIAlertAction напечатал меня Должен быть напечатан последним!

Но вместо этого он отображает:

Should be printed last!
UIAlertAction handler printed me

Ответы [ 2 ]

1 голос
/ 26 июня 2019

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

let alert = UIAlertController(title: "Ouch", message: "You didn't have to press me so hard!", preferredStyle: .alert)

alert.addAction(UIAlertAction(title: "Sorry", style: .default, handler: { action in

// code for action goes here

}))

self.present(alert, animated: true)
0 голосов
/ 26 июня 2019

UIAlertController предназначен для асинхронного запуска (поэтому он передает блок кода для выполнения при выполнении действия вместо предоставления возвращаемого значения)

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

private var currentlyShowingAlert = false

@IBAction func buttonTapped(_ sender: Any) {

    if currentlyShowingAlert {

        return

    }

    let alert = UIAlertController(title: "Ouch", message: "You didn't have to press me so hard!", preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "Sorry", style: .default, handler: { _ in
        self.handleAlert()
        self.alertCleanup()
    }))
    self.present(alert, animated: true, completion: nil)
    currentlyShowingAlert = true

}

func handleAlert() {

    print("UIAlertAction handler printed me")

}

func alertCleanup() {

     print("Should be printed last!")
     currentlyShowingAlert = false

}

Будьте осторожны при выполнении таких действий, как нажатие контроллеров представления (или чего-либо, где вызовы будутскладывать) в прямой реакции на нажатие кнопки.Когда основной поток занят, кнопку можно нажать несколько раз, прежде чем произойдет первый вызов buttonTapped, в этом случае buttonTapped можно будет вызывать много раз подряд, currentlyShowingAlert предотвратит эту проблему.

...