UIView动画和完成块

时间:2013-02-15 18:18:45

标签: ios objective-c

我尝试将tableview的偏移设置为动画,然后在完成块中将其向上移动。但是我的代码在完成块中没有做任何事情:

-(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");
                         }];
    }
}

"完成块"永远不会输出......任何想法?

编辑:

好的,所以它与我的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];
    }
}

添加刷新控件后,它不会触发完成块。如果我不'添加控件,它按预期工作。

编辑2:

K,所以如果我滚动表视图,则会触发完成块:

2013-02-15 13:37:06.266 [1922:14003] animating table view
2013-02-15 13:37:14.782 [1922:14003] completion block

所写的代码应该记录"完成块"在"动画表视图"之后,但是当我自己滚动表视图时,它有8秒的延迟原因。

"拉动刷新"看起来像:

enter image description here

2 个答案:

答案 0 :(得分:13)

我用过这个并且工作正常。它的替代解决方案。

[UIView animateWithDuration:0.5
                              delay:0.1
                            options: UIViewAnimationOptionCurveEaseOut
                         animations:^
         {
             CGRect frame = self.adBannerView.frame;

             self.adBannerView.frame = frame;
         }
                         completion:^(BOOL finished)
         {
         }];

尝试添加延迟和选项。

答案 1 :(得分:8)

我能够重现此问题并找到了解决方法。

使用UIScrollView继承的UITableView时,您无法更改其contentOffset不是可动画的属性。相反,您需要使用方法setContentOffset:animated:

所以,你需要做的是:

  1. 将您的视图控制器设置为UITableView代理。我参加了viewDidAppear
  2. 设置一个标志,因此您在委托中知道滚动发生是因为您已触发。
  3. 在委托方法- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView中,退回动画(您可以使用performSelector:afterDelay:添加延迟。
  4. 以下是代码:

    @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