iOS UIView 属性不使用 CABasicAnimation 进行动画处理

Posted

技术标签:

【中文标题】iOS UIView 属性不使用 CABasicAnimation 进行动画处理【英文标题】:iOS UIView properties don't animate with CABasicAnimation 【发布时间】:2012-01-10 13:20:00 【问题描述】:

当人们再次看到这个问题弹出时,我可以想象出大量的叹息。但是,我在这里、文档和谷歌都阅读了很多信息,但仍然没有找到解决方案。所以这里什么都没有。

我正在尝试重新创建 Facebook 登录屏幕,其中间距和位置通过键盘进行动画处理,以允许用户仍然看到所有输入字段和登录按钮。

当我使用kCAFillModeForwards 并将removedOnCompletion 设置为NO 时,此方法有效。但是,正如在另一个线程中所说的那样,这似乎只是在视觉上改变了属性,而实际的点击位置没有改变。因此,当用户看似在点击输入字段时,ios 会将其解释为对背景的点击。

所以我尝试设置新的位置和大小,但是当我这样做时,动画不会播放,它只是捕捉到新位置。将它放在addAnimation 调用之前和之后,无论有没有事务,都没有任何区别。

仍会调用委托方法,但您无法直观地看到任何动画。

if([notification name] == UIKeyboardWillShowNotification) 

    CGRect currBounds = self.loginTable.tableHeaderView.layer.bounds;
    CGSize newSize = CGSizeMake(self.loginTable.tableHeaderView.bounds.size.width, 60);
    CGPoint newPos = CGPointMake(self.loginTable.layer.position.x, self.loginTable.layer.position.x - 50);


    //[CATransaction begin];
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"bounds.size"];
    [animation setToValue:[NSValue valueWithCGSize:newSize]];
    [animation setDelegate:self];

    [self.loginTable.tableHeaderView.layer addAnimation:animation forKey:@"headerShrinkAnimation"];


    CABasicAnimation *formPosAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
    [formPosAnimation setToValue:[NSValue valueWithCGPoint:newPos]];
    [formPosAnimation setDelegate:self];        

    //formPosAnimation.removedOnCompletion = NO;
    //formPosAnimation.fillMode = kCAFillModeForwards;

    [self.loginTable.layer addAnimation:formPosAnimation forKey:@"tableMoveUpAnimation"];
    //[CATransaction commit];

    [self.loginTable.tableHeaderView.layer setBounds:CGRectMake(currBounds.origin.x, currBounds.origin.y, newSize.width, newSize.height)];
    [self.loginTable.layer setPosition:newPos];

【问题讨论】:

【参考方案1】:

我找到了一种让它工作的方法,不能说它是否是最好的方法,但它现在似乎正在工作。

关键是将几乎所有东西结合起来。所以我必须在我的动画上保留removedOnCompletionfillMode,同时还要更新我的animationDidStop 方法中的位置。不用设置两个动画参数也能正常工作,但最后你会看到一个小闪烁。

- (void)keyboardWillChange:(NSNotification *)notification 
newSize = CGSizeZero;
newPos = CGPointZero;

if([notification name] == UIKeyboardWillShowNotification) 
    newSize = CGSizeMake(self.loginTable.tableHeaderView.bounds.size.width, 60);
    newPos = CGPointMake(self.loginTable.layer.position.x, self.loginTable.layer.position.x - 50);
 else 
    newSize = CGSizeMake(self.loginTable.tableHeaderView.bounds.size.width, 150);
    newPos = CGPointMake(self.loginTable.layer.position.x, self.loginTable.layer.position.x + 50);


CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"bounds.size"];
[animation setToValue:[NSValue valueWithCGSize:newSize]];
[animation setDelegate:self];

animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;

[self.loginTable.tableHeaderView.layer addAnimation:animation forKey:@"headerShrinkAnimation"];

/*-----------------------------*/

CABasicAnimation *formPosAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
[formPosAnimation setToValue:[NSValue valueWithCGPoint:newPos]];
[formPosAnimation setDelegate:self];        

formPosAnimation.removedOnCompletion = NO;
formPosAnimation.fillMode = kCAFillModeForwards;

[self.loginTable.layer addAnimation:formPosAnimation forKey:@"tableMoveUpAnimation"];

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag 
NSLog(@"Animation did stop");

CGRect currBounds = self.loginTable.tableHeaderView.layer.bounds;

[self.loginTable.tableHeaderView.layer setBounds:CGRectMake(currBounds.origin.x, currBounds.origin.y, newSize.width, newSize.height)];
[self.loginTable.layer setPosition:newPos];

[self.loginTable.tableHeaderView.layer removeAnimationForKey:@"headerShrinkAnimation"];
[self.loginTable.layer removeAnimationForKey:@"tableMoveUpAnimation"];

【讨论】:

以上是关于iOS UIView 属性不使用 CABasicAnimation 进行动画处理的主要内容,如果未能解决你的问题,请参考以下文章

iOS开发-之UIView属性hidden, opaque, alpha, opacity的区别

iOS基础--UIView的常见属性

ios4--UIView的常见属性(尺寸和位置)

ios开发之--关于UIView的autoresizingMask属性的研究

UIView的使用

IOS、UIView、检测子视图隐藏状态变化