Блоки на Swift (animateWithDuration: анимация: завершение:)
У меня проблемы с работой блоков на Swift. Вот пример, который работал (без блока завершения):
UIView.animateWithDuration(0.07) {
self.someButton.alpha = 1
}
или альтернативно без замыкающего замыкания:
UIView.animateWithDuration(0.2, animations: {
self.someButton.alpha = 1
})
но как только я пытаюсь добавить блок завершения, он просто не будет работать:
UIView.animateWithDuration(0.2, animations: {
self.blurBg.alpha = 1
}, completion: {
self.blurBg.hidden = true
})
Автозаполнение дает мне completion: ((Bool) → Void)?
но не уверен, как заставить это работать. Также пробовал с завершающим замыканием, но получил ту же ошибку:
! Could not find an overload for 'animateWithDuration that accepts the supplied arguments
Обновление для Swift 3/4:
// This is how I do regular animation blocks
UIView.animate(withDuration: 0.2) {
<#code#>
}
// Or with a completion block
UIView.animate(withDuration: 0.2, animations: {
<#code#>
}, completion: { _ in
<#code#>
})
Я не использую трейлинг-закрытие для блока завершения, потому что думаю, что ему не хватает ясности, но если вам это нравится, вы можете увидеть ответ Тревора ниже.
Ответы
Ответ 1
параметр завершения в animateWithDuration принимает блок, который принимает один логический параметр. В быстром, как и в блоках Obj C, вы должны указать параметры, которые имеет замыкание:
UIView.animateWithDuration(0.2, animations: {
self.blurBg.alpha = 1
}, completion: {
(value: Bool) in
self.blurBg.hidden = true
})
Важная часть здесь (value: Bool) in
. Это говорит компилятору, что это замыкание принимает Bool с надписью "value" и возвращает void.
Для справки, если вы хотите написать замыкание, которое возвратило bool, синтаксис будет
{(value: Bool) -> bool in
//your stuff
}
Ответ 2
Завершение правильное, закрытие должно принимать параметр Bool
: (Bool) ->()
. Пытаться
UIView.animate(withDuration: 0.2, animations: {
self.blurBg.alpha = 1
}, completion: { finished in
self.blurBg.hidden = true
})
Ответ 3
Подчеркнуть сам по себе рядом с ключевым словом in
будет игнорировать вход
UIView.animateWithDuration(0.2, animations: {
self.blurBg.alpha = 1
}, completion: { _ in
self.blurBg.hidden = true
})
Ответ 4
Существует мое решение выше, основанное на принятом ответе выше. Он затеняет вид и скрывает его когда-то почти невидимым.
Swift 2
func animateOut(view:UIView) {
UIView.animateWithDuration (0.25, delay: 0.0, options: UIViewAnimationOptions.CurveLinear ,animations: {
view.layer.opacity = 0.1
}, completion: { _ in
view.hidden = true
})
}
Swift 3, 4, 5
func animateOut(view: UIView) {
UIView.animate(withDuration: 0.25, delay: 0.0, options: UIView.AnimationOptions.curveLinear ,animations: {
view.layer.opacity = 0.1
}, completion: { _ in
view.isHidden = true
})
}
Ответ 5
Вот, пожалуйста, это скомпилирует
Swift 2
UIView.animateWithDuration(0.3, animations: {
self.blurBg.alpha = 1
}, completion: {(_) -> Void in
self.blurBg.hidden = true
})
Swift 3, 4, 5
UIView.animate(withDuration: 0.3, animations: {
self.blurBg.alpha = 1
}, completion: {(_) -> Void in
self.blurBg.isHidden = true
})
Причина, по которой я сделал область Bool подчеркиванием, заключается в том, что вы не используете это значение, при необходимости вы можете заменить (_) на (значение: Bool)
Ответ 6
Иногда вы хотите бросить это в переменной для анимации по-разному в зависимости от ситуации. Для этого вам нужно
let completionBlock : (Bool) -> () = { _ in
}
Или вы можете использовать одинаково многословное:
let completionBlock = { (_:Bool) in
}
Но в любом случае вам нужно указать Bool
где-нибудь.
Ответ 7
SWIFT 3.x + 4.x
Я хотел бы сделать обновление и упростить вещи.
Пример ниже реализован в любом view
он скрывается медленно и когда он полностью прозрачен; удаляет себя из родительского view
Переменная ok
всегда возвращает true
с завершением анимации.
alpha = 1
UIView.animate(withDuration: 0.5, animations: {
self.alpha = 0
}) { (ok) in
print("Ended \(ok)")
self.removeFromSuperview()
}