Perform a task (in iOS) after animation has finish

2019-03-12 21:13发布

So I have this line of code:

[tableView setContentOffset:point animated:YES];

and I want to run another piece of code after the animation ends. My attempt was to throw the animating code (setContentOffset) in a separate method and calling it using:

[self performSelectorOnMainThread:@selector(scrollMethod:) withObject:sender waitUntilDone:YES];

The problem is that the method returns immediately, not after the animation is finished, even though waitUntilDone is YES, but apparently that is how animation works.

I know that I can use thread waiting but it is not clean, so I will only use it as a last resort. (Maybe I would use this if I know the time it takes the scrolling animation to happen.)

Any ideas on how to go about this are welcome.

(P.S. The scenario is this: I am showing a popover, which is displayed perfectly when there is no keyboard, however, if the keyboard is visible, the popover's height shrinks which sometimes reduces it to almost border only. So just before showing the popover, I want to scroll the view upwards so that the popover never pops in the keyboard.)

4条回答
Juvenile、少年°
2楼-- · 2019-03-12 21:25

Try to use this method:

[UIView animateWithDuration:0.6f
                      delay:0.0f
                    options:UIViewAnimationOptionCurveEaseOut
                 animations:^{
                     // Do your animations here.
                 }
                 completion:^(BOOL finished){
                     if (finished) {
                         // Do your method here after your animation.
                     }
                 }];
查看更多
地球回转人心会变
3楼-- · 2019-03-12 21:32

You can create animations and tell them directly to perform a block after they're done.

Here's an alternative that may play nicer with the UITableView's animations.

[UIView beginAnimations:nil context:sender];
[UIView setDelegate:self];
[UIView setDidStopSelector:@selector(scrollMethod:)];
[tableView setContentOffset:point];
[UIView commitAnimations];

And make sure to implement your scrollMethod: with this signature:

- (void)scrollMethod:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context

You can use the context to know which sender you have. Read the UIView docs for more on UIView animations.

查看更多
何必那么认真
4楼-- · 2019-03-12 21:44

For a scrollView, tableView or collectionView if you do something like this:

[self.collectionView setContentOffset:CGPointMake(self.collectionView.contentOffset.x+260.0,
                                                      self.collectionView.contentOffset.y)
                                 animated:YES];

then you'll get back a:

-(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView

when the scroll finishes.

You do NOT get this callback if the user moves the view.

查看更多
Bombasti
5楼-- · 2019-03-12 21:49

UITableView inherits setContentOffset:animated: from its superclass, UIScrollView. Check out the scrollViewDidEndScrollingAnimation: method of UIScrollViewDelegate.

查看更多
登录 后发表回答