UIView Animate and completion block
ios, objective-c
Solution
I was able to reproduce this issue and found a workaround.
When using a `UIScrollView`, which `UITableView` inherits from, you can't change its `contentOffset` is not an animatable property. Instead, you need to use the method `setContentOffset:animated:`.
So, what you need to do is as follows:
- Set your view controller as the `UITableView` delegate. I did in on `viewDidAppear`.
- Set a flag, so you know in the delegate that the scroll happened because you triggered.
- In the delegate method `- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView`, bounce back the animation (you could here add a delay by using `performSelector:afterDelay:`.
Here's the code:
@interface MyViewController ()
@property (assign, nonatomic) BOOL shouldReturn;
@end
@implementation MyViewController
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (TRUE) {
NSLog(@"animating table view");
self.shouldReturn = YES;
self.tableView.delegate = self;
[self.tableView setContentOffset:
CGPointMake(self.tableView.contentOffset.x,
self.tableView.contentOffset.y - 60)
animated:YES];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
if (TRUE) {
UIRefreshControl *refresh = [[UIRefreshControl alloc] init];
refresh.attributedTitle = [[NSAttributedString alloc] initWithString:@"Pull to Refresh"];
[refresh addTarget:self action:@selector(refreshTableView:) forControlEvents:UIControlEventValueChanged];
[self setRefreshControl:refresh];
}
}
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
if (self.shouldReturn) {
self.shouldReturn = NO;
[self.tableView setContentOffset:CGPointZero animated:YES];
}
}
@end
Problem
I'm trying to animate a tableview's offset down, then in the completion block would move it back up. But my code is not doing anything in the completion block: ``` -(void)viewDidAppear:(BOOL)animated { if (TRUE) { NSLog(@"animating table view"); [UIView animateWithDuration:.25 animations:^{ self.tableView.contentOffset = CGPointMake(self.tableView.contentOffset.x, self.tableView.contentOffset.y - 60); } completion:^(BOOL finished){ NSLog(@"completion block"); }]; } } ``` "completion block" never gets outputted... any ideas? EDIT: Ok, so it has something to do with my UIREfreshControl: ``` - (void)viewDidLoad { [super viewDidLoad]; if (TRUE) { UIRefreshControl *refresh = [[UIRefreshControl alloc] init]; refresh.attributedTitle = [[NSAttributedString alloc] initWithString:@"Pull to Refresh"]; [refresh addTarget:self action:@selector(refreshTableView:) forControlEvents:UIControlEventValueChanged]; [self setRefreshControl:refresh]; } } ``` When the refresh controll is added, it won't fire off the completion block. if i dont' add the control, it works as intended. EDIT 2: K, so if i scroll the table view, the completion block is then fired: ``` 2013-02-15 13:37:06.266 [1922:14003] animating table view 2013-02-15 13:37:14.782 [1922:14003] completion block ``` the code as written should log "completion block" right after "animating table view", but it has a 8 second delay cause thats when i scrolled the table view myself. how the "Pull to Refresh" looks like: