У меня есть кнопка, которая показывает представление и которая автоматически уходит после указанного интервала времени. Теперь, если кнопка снова нажата, когда представление уже видно, оно должно исчезнуть и отобразить новое представление, а таймер для нового представления будет сброшен.Обратный вызов анимации, изменяющий другую переменную
На нажатия кнопки я следующий код:
func showToast() {
timer?.invalidate()
timer = nil
removeToast()
var appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
var toAddView = appDelegate.window!
toastView = UIView(frame: CGRectMake(0, toAddView.frame.height, toAddView.frame.width, 48))
toastView.backgroundColor = UIColor.darkGrayColor()
toAddView.addSubview(toastView)
timer = NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: Selector("removeToast"), userInfo: nil, repeats: false)
UIView.animateWithDuration(0.5, animations: {() -> Void in
self.toastView.frame.origin.y -= 48
})
}
Чтобы удалить тост я иметь следующий код:
func removeToast() {
if toastView != nil {
UIView.animateWithDuration(0.5,
animations: {() -> Void in
self.toastView.frame.origin.y += 48
},
completion: {(completed: Bool) -> Void in
self.toastView.removeFromSuperview()
self.toastView = nil
})
}
}
Теперь даже если я сбросить таймер каждый раз, делая timer.invalidate()
я получаю два вызова в removeToast()
, который удаляет вновь вставленный вид. Может быть, что UIView.animate
вызывает проблемы, я не получаю отладки двух обратных вызовов для removeToast()
. Демонстрационный проект, показывающий поведение является here
Примечание: Я нашел некоторую почту о том, чтобы использовать dispatch_after()
вместо таймера, также, как спросил @ jervine10, но не хватает моего сценария. Как будто я использую dispatch_after
, тогда сложно аннулировать вызов GCD. Есть что-то, что можно было бы сделать с помощью NSTimers. Я думаю, что NSTimers предназначены для этого, и есть что-то, что я делаю неправильно.
Просто за то, что это стоит, я получаю то же самое, в результате чего таймер не будет недействительным, и даже установить его в ноль, он снова называет себя. – AndyDunn
@AndyDunn У меня было обходное решение проблемы, удалив блок завершения удаления toastView. Теперь я сохраняю файл toastView и скрываю его вместо удаления из супервизора, но все равно получаю два вызова таймера. – meteors
В конце я просто добавил флаг, чтобы проверить, следует ли остановить таймер. Далеко не идеален, но работает надежно. – AndyDunn