Blocks on Swift (animateWithDuration:animations:completion:)
IosSwiftClosuresIos Problem Overview
I'm having trouble making the blocks work on Swift. Here's an example that worked (without completion block):
UIView.animateWithDuration(0.07) {
self.someButton.alpha = 1
}
or alternatively without the trailing closure:
UIView.animateWithDuration(0.2, animations: {
self.someButton.alpha = 1
})
but once I try to add the completion block it just won't work:
UIView.animateWithDuration(0.2, animations: {
self.blurBg.alpha = 1
}, completion: {
self.blurBg.hidden = true
})
The autocomplete gives me completion: ((Bool) -> Void)?
but not sure how to make it work. Also tried with trailing closure but got the same error:
! Could not find an overload for 'animateWithDuration that accepts the supplied arguments
Update for 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#>
})
I don't use the trailing closure for the completion block because I think it lacks clarity, but if you like it then you can see Trevor's answer below.
Ios Solutions
Solution 1 - Ios
The completion parameter in animateWithDuration
takes a block which takes one boolean parameter. In Swift, like in Obj-C blocks, you must specify the parameters that a closure takes:
UIView.animateWithDuration(0.2, animations: {
self.blurBg.alpha = 1
}, completion: {
(value: Bool) in
self.blurBg.hidden = true
})
The important part here is the (value: Bool) in
. That tells the compiler that this closure takes a Bool labeled 'value' and returns Void.
For reference, if you wanted to write a closure that returned a Bool, the syntax would be
{(value: Bool) -> bool in
//your stuff
}
Solution 2 - Ios
The completion is correct, the closure must accept a Bool
parameter: (Bool) -> ()
. Try
UIView.animate(withDuration: 0.2, animations: {
self.blurBg.alpha = 1
}, completion: { finished in
self.blurBg.hidden = true
})
Solution 3 - Ios
Underscore by itself alongside the in
keyword will ignore the input
Swift 2
UIView.animateWithDuration(0.2, animations: {
self.blurBg.alpha = 1
}, completion: { _ in
self.blurBg.hidden = true
})
Swift 3, 4, 5
UIView.animate(withDuration: 0.2, animations: {
self.blurBg.alpha = 1
}, completion: { _ in
self.blurBg.isHidden = true
})
Solution 4 - Ios
There is my solution above based on accepted answer above. It fades out a view and hiddes it once almost invisible.
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
})
}
Solution 5 - Ios
Here you go, this will compile
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
})
The reason I made the Bool area an underscore is because you not using that value, if you need it you can replace the (_) with (value : Bool)
Solution 6 - Ios
Sometimes you want to throw this in a variable to animate in different ways depending on the situation. For that you need
let completionBlock : (Bool) -> () = { _ in
}
Or you could use the equally verbose:
let completionBlock = { (_:Bool) in
}
But in any case, you have have to indicate the Bool
somewhere.
Solution 7 - Ios
SWIFT 3.x + 4.x
I'd like to make an update and simplify the things.
Example below is implemented in any view
it is hiding slowly and when it is completely transparent; removes it self from parent view
ok
variable will always returns true
with animation termination.
alpha = 1
UIView.animate(withDuration: 0.5, animations: {
self.alpha = 0
}) { (ok) in
print("Ended \(ok)")
self.removeFromSuperview()
}