Таймер обратного отсчета, показанный внутри кнопки в UIAlertController, затем включите быстрое нажатие кнопки
Можно ли создать UIAlertController, который имеет кнопку, которая изначально отключена и имеет 5, затем 4, затем 3..2..1, а затем -.
Я хочу, чтобы пользователь действительно прочитал сообщение в контроллере, и я думаю, что это будет достаточно раздражающим, чтобы на самом деле помешать им бездумно нажать OK
Если это возможно, как бы я начал делать это?
Спасибо
3 ответа
Это немного странно, так как мы пытаемся изменить свойство только для чтения UIAlertAction
, Тем не менее, это прекрасно работает для меня. В качестве альтернативы вы можете создать свой собственный контроллер представления, который выглядит как UIAlertController:
var timer: NSTimer?
var timerCount: Int = 5
func showAlertView() {
let alertController = UIAlertController(title: "Title", message: "Message of alert", preferredStyle: .Alert)
let okAction = UIAlertAction(title: "Ok", style: .Default, handler: nil)
okAction.enabled = false
alertController.addAction(okAction)
alertController.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))
presentViewController(alertController, animated: true) {
self.timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(self.countDownTimer), userInfo: nil, repeats: true)
}
}
func countDownTimer() {
timerCount -= 1
let alertController = presentedViewController as! UIAlertController
let okAction = alertController.actions.first
if timerCount == 0 {
timer?.invalidate()
timer = nil
okAction?.setValue("Ok", forKey: "title")
okAction?.enabled = true
} else {
okAction?.setValue("Ok \(timerCount)", forKey: "title")
}
}
Вот как это выглядит:
Да, вы можете включить действие предупреждения после определенного интервала следующим образом:
func showAlert() {
let alertview = UIAlertController(title: "title", message: "msg", preferredStyle: .Alert)
let action = UIAlertAction(title: "OK", style: .Default, handler: nil)
alertview.addAction(action)
self.presentViewController(alertview, animated: true) { () -> Void in
action.enabled = false
NSTimer.scheduledTimerWithTimeInterval(5, target: self, selector: "enableBtn:", userInfo: action, repeats: false)
}
}
func enableBtn(t: NSTimer){
let info = t.userInfo as! UIAlertAction
info.enabled = true
}
Надеюсь, это поможет вам:)
Это мой вариант принятого ответа
Я обнаружил, что мне нужно аннулировать таймер для каждой опции, предоставленной пользователю вUIAlertController
в противном случае таймер продолжал бы работать в фоновом режиме, а также вызывал некоторые другие проблемы.
Моя собственная реализация немного сложнее и имеет больше возможностей, но суть изложена ниже. Также обновлено до Xcode 14
var timer: Timer?
var timerCount: Int = 5
func showAlertView() {
let alertController = UIAlertController(title: "Title", message: "Message of alert", preferredStyle: .Alert)
let okAction = UIAlertAction(title: "Ok", style: .default, handler: nil)
okAction.isEnabled = false
alertController.addAction(okAction)
alertController.addAction(UIAlertAction(title: "No", style: .cancel, handler: {( action: UIAlertAction ) in
print("No")
self.invalidateAlertControllerCountDownTimer()
}))
alertController.addAction(UIAlertAction(title: "Maybe", style: .cancel, handler: {( action: UIAlertAction ) in
print("Maybe")
self.invalidateAlertControllerCountDownTimer()
}))
present(alertController, animated: true) {
self.timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.alertControllerCountDownTimer), userInfo: nil, repeats: true)
}
}
@objc func alertControllerCountDownTimer() {
timerCount -= 1
let alertController = presentedViewController as! UIAlertController
if let alertController = alertController {
let okAction = alertController.actions.first
if timerCount == 0 {
invalidateAlertControllerCountDownTimer()
okAction?.setValue("Ok", forKey: "title")
okAction?.isEnabled = true
} else {
okAction?.setValue("Ok \(timerCount)", forKey: "title")
}
}
}
func invalidateAlertControllerCountDownTimer() {
timer?.invalidate()
timer = nil
timerCount = 5
}