Here is some code I struggle with for a while.
If you start the fade in animation, the label text fades in. If I start the fade out animation the the label text fades ou
The easiest way would be to use:
[UIView animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion]
and add the fadeOut
call to the completion
block. The documentation might help answer any questions you have.
If you can't use the block version for some reason, then you'll have to set a delegate ([UIView setAnimationDelegate:(id)delegate]
) and a selector with ([UIView setAnimationDidStopSelector:]
) that the delegate will respond to.
Again, see the documentation for more details.
The fade in and fade out animations can be combined using UIView.animate(withDuration: animations:)
UIView.animate(withDuration: animationDuration, animations: {
myView.alpha = 0.75
myView.alpha = 1.0
})
Swift 4 If you need just one pulse when clicking the button, use that:
@IBAction func didPressButton(_ sender: UIButton) {
self.someView.alpha = 0
UIView.animate(withDuration: 0.4,
delay: 0,
options: [.curveEaseInOut, .autoreverse],
animations: {
self.someView.alpha = 1
},
completion: { _ in
self.someView.alpha = 0
})
}
When you call the fadeIn
and fadeOut
methods back to back like you're doing, the code is run instantaneously, so you'll only see animation from the last method called. UIView block based animation provides a completion handler, which seems to be exactly what you're looking for. So your code might looks something like this:
-(IBAction)startFade:(id)sender {
[_label setAlpha:0.0f];
//fade in
[UIView animateWithDuration:2.0f animations:^{
[_label setAlpha:1.0f];
} completion:^(BOOL finished) {
//fade out
[UIView animateWithDuration:2.0f animations:^{
[_label setAlpha:0.0f];
} completion:nil];
}];
}
Swift:
@IBAction func startFade(_ sender: AnyObject) {
label.alpha = 0.0
// fade in
UIView.animate(withDuration: 2.0, animations: {
label.alpha = 1.0
}) { (finished) in
// fade out
UIView.animate(withDuration: 2.0, animations: {
label.alpha = 0.0
})
}
}
that does the job for you (the _label
is your label);
- (IBAction)startFade:(id)sender {
[_label setAlpha:0.f];
[UIView animateWithDuration:2.f delay:0.f options:UIViewAnimationOptionCurveEaseIn animations:^{
[_label setAlpha:1.f];
} completion:^(BOOL finished) {
[UIView animateWithDuration:2.f delay:0.f options:UIViewAnimationOptionCurveEaseInOut animations:^{
[_label setAlpha:0.f];
} completion:nil];
}];
}
Based on @holex's answer, but simplified a bit (as commented):
- (IBAction)startFade:(id)sender {
[_label setAlpha:0.f];
[UIView animateWithDuration:2.f
delay:0.f
options:UIViewAnimationOptionCurveEaseIn
| UIViewAnimationOptionAutoreverse
animations:^{
[_label setAlpha:1.f];
}
completion:nil];
}