Reputation: 380
I have a method I'm writing called "animatePulseAtSpeed: completion:" which takes a completion block which will be used in an UIView "animateWithDuration: delay: options: animations: completion:" call inside this method as shown below. The problem is I want to add a line of my own to be executed at the same time that this completion block is called. For example, I may want to reposition the frame of the "rightPulse" UIView referred to in the code below BUT only after the UIView animation below is carried out. So it seems that the UIView completion block is the logical place to put the command to reposition the "rightPulse" UIView frame. But if I put a line in the UIView completion block to reposition the frame, then it seems that I lose the ability for an outside object to supply a completion block when it calls the method below. It seems that there is an either/or problem: Either I use the "animateWithDuration" completion block myself or I can have an outside object supply the completion block, but I can't satisfy both needs at the same time.
Is there any elegant or simple way to modify the code below so that I let an outside object supply a completion block when it calls this method BUT I'm still able to add a command to this same completion block so that it also carries out the additional action I want (e.g., reposition the "rightPulse" frame) at the same time?
The best solution I've been able to think of is to use a "performSelector: withDelay" method to reset the "rightPulse" UIView position so that I don't need to use the "animateWithDuration" completion block for that. But that seems like a bit of a kludge since the completion block seems to be the natural place for the position reset to be.
- (void)animatePulseAtSpeed:(CGFloat)speed completion: (void(^)(BOOL finished)) completion {
…….
[UIView animateWithDuration:0.25
delay:1.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{self.rightPulse.alpha=0.0;}
completion:completion]; }
Upvotes: 1
Views: 78
Reputation: 534895
Do not pass completion
to animateWithDuration
. Instead, make a new block in which you call completion()
followed by your own commands, and pass that to animateWithDuration
.
Here's a similar example from my own code:
func displayActivityIndicatorWhileDoing (whatToDo : () -> ()) {
let act = UIActivityIndicatorView(activityIndicatorStyle: .WhiteLarge)
act.center = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds))
self.view.addSubview(act)
self.view.bringSubviewToFront(act)
act.startAnimating()
dispatch_async(dispatch_get_main_queue()) {
whatToDo()
act.removeFromSuperview()
}
}
That's Swift, not Objective-C, and it's not an animation block, but it is a block (a closure). The idea is that caller passes me a block, and I wrap that block in the display of an activity view and call it. So the block means "do this, plus whatever yummy goodness you are going to add". That's exactly the situation you are describing.
Upvotes: 3