Таймер обратного отсчета, показанный внутри кнопки в 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
  }
Другие вопросы по тегам