uiview animatewithduration在视图被取消后继续完成

时间:2013-02-13 17:08:10

标签: objective-c uiviewanimation

我有一个包含UIView动画的modelViewController。当动画块完成时,它会调用自身,从而循环。

当我关闭调用[_starView removeFromSuperview]的modelViewController(dismissInfo)时,该函数会被反复调用,并且NSLog行每秒打印多次。

@implementation InfoVC
{
    NSArray *imgs;
    NSString *currentImg;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    _imageview.contentMode = UIViewContentModeLeft;
    _imageviewUnder.contentMode = UIViewContentModeLeft;

    imgs = [NSArray arrayWithObjects:
            @"01.jpg",
            @"02.jpg",
            @"03.jpg",
            @"04.jpg",
            @"05.jpg",
            @"06.jpg",
            nil];

    _imgInt = (arc4random()%6);

    [self initialImage];
}

- (void)viewWillAppear:(BOOL)animated{
}


- (void)viewDidAppear:(BOOL)animated{
    NSLog(@"viewDidAppear");
}

- (void)initialImage
{        
    _starView.contentMode = UIViewContentModeLeft;
    _imageviewUnder.contentMode = UIViewContentModeLeft;

    currentImg = [imgs objectAtIndex:_imgInt];
    UIImage *image = [UIImage imageNamed:currentImg];

    _starView = [[UIImageView alloc] initWithImage:image];

    // Size the image view to the image (it's bigger)
    _starView.bounds = CGRectMake(0.0, 44.0, 416.0, 416.0);

    NSLog(@"tarView.center %@", NSStringFromCGPoint(_starView.center) );

    _starView.alpha=1;

    int nextImgInt = _imgInt + 1 ;

    if (nextImgInt>5)
    {
        nextImgInt=0;
    }

    NSString *nextImg = [imgs objectAtIndex:nextImgInt];
    UIImage *nextImage = [UIImage imageNamed:nextImg];
    [_imageviewUnder setImage:nextImage];

    [self.view sendSubviewToBack:_imageviewUnder];


    _imgInt++;

    if (_imgInt>5) {
        _imgInt=0;
    }

    [UIView setAnimationBeginsFromCurrentState:YES];

    [UIView animateWithDuration:7.6f
                          delay:0.1f
                        options:UIViewAnimationCurveLinear
                     animations:^{
                         [_starView setCenter:CGPointMake(112, 208)];
                         [_starView setAlpha:0.0f];
                     }
                     completion:^(BOOL finished){
                         [_starView removeFromSuperview];
                         [self initialImage];
                     }];

    [self.view insertSubview:_starView atIndex:1];

}


- (void)visitTwitter
{    
    NSURL *URL = [NSURL URLWithString:@"http://twitter.com/"];
    SVWebViewController *webViewController = [[SVWebViewController alloc] initWithURL:URL];
    [self.navigationController pushViewController:webViewController animated:YES];

}



- (IBAction)dismissInfo:(id)sender
{
    [self cleanup];
    [self dismissModalViewControllerAnimated:YES];
}


- (void)cleanup
{
    [_starView.layer removeAllAnimations];
    [self.view.layer removeAllAnimations];
    [_starView removeFromSuperview];
}

- (void)viewDidUnload
{
    [self cleanup];
    [super viewDidUnload];
}

@end

3 个答案:

答案 0 :(得分:0)

让自己成为一个动画标志,在viewDidLoad中设置为true,在清理时设置为false。然后在initialImage方法中检查它:

if ( ! animating )
    return;

答案 1 :(得分:0)

这是我第二次碰到这个。一个可能的原因是该方法在viewDidLoad中被初始化,但是子视图和图像没有及时准备好(似乎动画循环的第一次传递不能为机器添加重影)。

我将调用移至ViewDidAppear,确保显示初始化图像以停止白色闪光。最后是模态窗口中的无限动画

- (void)viewDidLoad
{
    [super viewDidLoad];

    _imageview.contentMode = UIViewContentModeLeft;
    _imageviewUnder.contentMode = UIViewContentModeLeft;

    imgs = [NSArray arrayWithObjects:
            @"01.jpg",
            @"02.jpg",
            @"03.jpg",
            @"04.jpg",
            @"05.jpg",
            @"06.jpg",
            nil];

    _imgInt = (arc4random()%6);

    currentImg = [imgs objectAtIndex:_imgInt];
    UIImage *image = [UIImage imageNamed:currentImg];
    [_imageviewUnder setImage:image];
}

- (void)viewDidAppear:(BOOL)animated{
    [self initialImage];
}

- (void)initialImage
{        
    currentImg = [imgs objectAtIndex:_imgInt];
    UIImage *image = [UIImage imageNamed:currentImg];

    _starView = [[UIImageView alloc] initWithImage:image];

    // Size the image view to the image (it's bigger)
    _starView.bounds = CGRectMake(0.0, 44.0, 416.0, 416.0);

    NSLog(@"initialImage");

    _starView.alpha=1;

    [self.view insertSubview:_starView atIndex:1];

    int nextImgInt = _imgInt + 1 ;

    if (nextImgInt>5)
    {
        nextImgInt=0;
    }

    NSString *nextImg = [imgs objectAtIndex:nextImgInt];
    UIImage *nextImage = [UIImage imageNamed:nextImg];
    [_imageviewUnder setImage:nextImage];

    [self.view sendSubviewToBack:_imageviewUnder];

    _imgInt++;

    if (_imgInt>5) {
        _imgInt=0;
    }

    [UIView setAnimationBeginsFromCurrentState:YES];

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:7.6];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationCurve:UIViewAnimationCurveLinear];
    //[UIView setAnimationDidStopSelector:@selector(initialImage) ];
    [_starView setCenter:CGPointMake(112, 208)];
    [_starView setAlpha:0.0f];
    [UIView commitAnimations];

    [self performSelector:@selector(initialImage) withObject:nil afterDelay:7.6];
}

- (IBAction)dismissInfo:(id)sender
{
    [self cleanup];
    [self dismissModalViewControllerAnimated:YES];
}

- (void)cleanup
{
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
    [_starView.layer removeAllAnimations];
    [self.view.layer removeAllAnimations];
    [_starView removeFromSuperview];
}

答案 2 :(得分:0)

如果您只是想创建一个循环动画,最好的办法是使用选项:' UIViewAnimationOptions Repeat '。例如:

[UIView animateWithDuration:2.0
                      delay:0.0f
                    options:UIViewAnimationOptionRepeat
                 animations:^{
                            [myUIViewThing setCenter:CGPointMake(myUIViewThing.center.x - 100, myUIViewThing.center.y)];
                             }
                 completion:nil];