CABasicAnimation 在旋转期间被忽略

发布于 2024-09-25 07:07:44 字数 3130 浏览 1 评论 0原文

我有一个 UIView,它在layoutSubviews 方法中根据 iPad 的方向重新定位其子视图。在layoutSubviews方法中,我有一个CABasicAniamtion,它应该为子视图的重新定位设置动画。动画被设置为特定的持续时间,但该持续时间将被忽略并立即发生重新定位。我知道动画正在触发,因为我看到 AnimationDidStart 和 AnimationDidStop 方法被触发。我知道这与 UIView 的 CALayers 有关,但我在网上找不到任何内容来解释如何解决此问题。任何帮助将不胜感激。

    if([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown)
    {
        NSLog(@"Orientation: Portrait");

        //Hide icon

        CABasicAnimation *iconAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
        iconAnimation.fromValue = [NSValue valueWithCGPoint:[iconImageView center]];
        iconAnimation.toValue = [NSValue valueWithCGPoint:iconThinPosition];
        iconAnimation.duration = 2.7f;
        iconAnimation.autoreverses = NO;
        iconAnimation.repeatCount = 1;
        iconAnimation.delegate = self;
        [iconImageView.layer addAnimation:iconAnimation forKey:@"position"];
        //[iconImageView setCenter:iconThinPosition];

        [iconImageView.layer setPosition:iconThinPosition];
        //[iconImageView setTransform: CGAffineTransformIdentity];

        CABasicAnimation *textAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
        textAnimation.fromValue = [NSValue valueWithCGPoint:[textImageView center]];
        textAnimation.toValue = [NSValue valueWithCGPoint:textThinPosition];
        textAnimation.duration = 2.7f;
        textAnimation.autoreverses = NO;
        textAnimation.repeatCount = 1;
        textAnimation.delegate = self;
        [textImageView.layer addAnimation:textAnimation forKey:@"position"];        
        [textImageView.layer setPosition:textThinPosition];

    }
    else if([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft || [[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight) 
    {
        NSLog(@"Orientation: Landscape");        

        // Show Icon
        CABasicAnimation *iconAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
        iconAnimation.fromValue = [NSValue valueWithCGPoint:[iconImageView center]];
        iconAnimation.toValue = [NSValue valueWithCGPoint:iconShownPosition];
        iconAnimation.duration = 2.7f;
        iconAnimation.autoreverses = NO;
        iconAnimation.repeatCount = 1;
        iconAnimation.delegate = self;
        [iconImageView.layer addAnimation:iconAnimation forKey:@"position"];
        [iconImageView.layer setPosition:iconShownPosition];

        CABasicAnimation *textAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
        textAnimation.fromValue = [NSValue valueWithCGPoint:[textImageView center]];
        textAnimation.toValue = [NSValue valueWithCGPoint:textShownPosition];
        textAnimation.duration = 2.7f;
        textAnimation.autoreverses = NO;
        textAnimation.repeatCount = 1;
        textAnimation.delegate = self;
        [textImageView.layer addAnimation:textAnimation forKey:@"position"];
        [textImageView.layer setPosition:textShownPosition];
    }
}

I have a UIView that in the layoutSubviews method repositions its subviews based on the orientation of the iPad. Within the layoutSubviews method I have a CABasicAniamtion that is supposed to animate the repositioning of the subviews. The animations are set to specific duration but this duration is being ignored and repositioning happens immediately. I know the animations are firing because I am seeing the AnimationDidStart and AnimationDidStop methods being fired. I know this has something to do with the CALayers of the UIView but I can not find anything on the web to explain how to fix this. Any help would be appreciated.

    if([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown)
    {
        NSLog(@"Orientation: Portrait");

        //Hide icon

        CABasicAnimation *iconAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
        iconAnimation.fromValue = [NSValue valueWithCGPoint:[iconImageView center]];
        iconAnimation.toValue = [NSValue valueWithCGPoint:iconThinPosition];
        iconAnimation.duration = 2.7f;
        iconAnimation.autoreverses = NO;
        iconAnimation.repeatCount = 1;
        iconAnimation.delegate = self;
        [iconImageView.layer addAnimation:iconAnimation forKey:@"position"];
        //[iconImageView setCenter:iconThinPosition];

        [iconImageView.layer setPosition:iconThinPosition];
        //[iconImageView setTransform: CGAffineTransformIdentity];

        CABasicAnimation *textAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
        textAnimation.fromValue = [NSValue valueWithCGPoint:[textImageView center]];
        textAnimation.toValue = [NSValue valueWithCGPoint:textThinPosition];
        textAnimation.duration = 2.7f;
        textAnimation.autoreverses = NO;
        textAnimation.repeatCount = 1;
        textAnimation.delegate = self;
        [textImageView.layer addAnimation:textAnimation forKey:@"position"];        
        [textImageView.layer setPosition:textThinPosition];

    }
    else if([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft || [[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight) 
    {
        NSLog(@"Orientation: Landscape");        

        // Show Icon
        CABasicAnimation *iconAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
        iconAnimation.fromValue = [NSValue valueWithCGPoint:[iconImageView center]];
        iconAnimation.toValue = [NSValue valueWithCGPoint:iconShownPosition];
        iconAnimation.duration = 2.7f;
        iconAnimation.autoreverses = NO;
        iconAnimation.repeatCount = 1;
        iconAnimation.delegate = self;
        [iconImageView.layer addAnimation:iconAnimation forKey:@"position"];
        [iconImageView.layer setPosition:iconShownPosition];

        CABasicAnimation *textAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
        textAnimation.fromValue = [NSValue valueWithCGPoint:[textImageView center]];
        textAnimation.toValue = [NSValue valueWithCGPoint:textShownPosition];
        textAnimation.duration = 2.7f;
        textAnimation.autoreverses = NO;
        textAnimation.repeatCount = 1;
        textAnimation.delegate = self;
        [textImageView.layer addAnimation:textAnimation forKey:@"position"];
        [textImageView.layer setPosition:textShownPosition];
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

憧憬巴黎街头的黎明 2024-10-02 07:07:44

我想知道它是否没有被忽略,因为当调用您的layoutSubviews 时已经有一个动画事务正在进行中。您可以尝试确认这一点的一件事是覆盖 -didRotateFromInterfaceOrientation 并从那里调用您的layoutSubviews。看看你的观点是否生动起来。

- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
//    [self layoutSubviews];
    // Give it a second to settle after the rotation and then call
    // layoutSuviews explicitly.
    [self performSelector:@selector(layoutSubviews) withObject:nil afterDelay:1.0f];
}

另一件需要考虑的事情是,由于您只是对 UIView 图层的位置进行动画处理,因此您可以使用 UIView 动画而不是显式动画。像这样的东西:

    if([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown)
    {
        NSLog(@"Orientation: Portrait");

        //Hide icon
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:2.7f];
        [iconImageView setCenter:iconThinPosition];
        [textImageView setCenter:textThinPosition];
        [UIView commitAnimations];

    }
    else if([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft || [[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight) 
    {
        NSLog(@"Orientation: Landscape");        

        // Show Icon
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:2.7f];
        [iconImageView setCenter:iconShownPosition];
        [textImageView setCenter:textShownPosition];
        [UIView commitAnimations];

    }

I wonder if it isn't being ignored so much as there is already an animation transaction in progress when your layoutSubviews gets called. One thing you could try to confirm this is to override -didRotateFromInterfaceOrientation and call your layoutSubviews from there. See if your views animate then.

- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
//    [self layoutSubviews];
    // Give it a second to settle after the rotation and then call
    // layoutSuviews explicitly.
    [self performSelector:@selector(layoutSubviews) withObject:nil afterDelay:1.0f];
}

Another thing to think about is that since you are only animating the position of the UIView's layer, you could use UIView animations instead of explicit animation. Something like:

    if([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown)
    {
        NSLog(@"Orientation: Portrait");

        //Hide icon
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:2.7f];
        [iconImageView setCenter:iconThinPosition];
        [textImageView setCenter:textThinPosition];
        [UIView commitAnimations];

    }
    else if([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft || [[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight) 
    {
        NSLog(@"Orientation: Landscape");        

        // Show Icon
        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:2.7f];
        [iconImageView setCenter:iconShownPosition];
        [textImageView setCenter:textShownPosition];
        [UIView commitAnimations];

    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文