简体   繁体   English

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

[英]iOS UIView properties don't animate with CABasicAnimation

I can imagine a far amount of sighs when people see this question popup again . 当人们再次看到这个问题弹出窗口时,我可以想象出很多的叹息。 However, I have read through a lot of information both here, in the documentation and via Google and still haven't found a solution. 但是,我在这里,文档和谷歌都阅读了很多信息,但仍然没有找到解决方案。 So here goes nothing. 所以这里什么都没有。

I'm trying to recreate the Facebook login screen, where the spacing and position animates with the keyboard to allow the user to still see all the input fields and login button. 我正在尝试重新创建Facebook登录屏幕,其中间距和位置使用键盘设置动画,以允许用户仍然可以看到所有输入字段和登录按钮。

This works when I use the kCAFillModeForwards and set removedOnCompletion to NO . 这在我使用kCAFillModeForwards并将removedOnCompletion设置为NO But, as said in another thread here on SO, this seems to only visually change properties and the actual tap position isn't changed. 但是,正如在SO上的另一个帖子中所说,这似乎只是在视觉上改变了属性,并且实际的敲击位置没有改变。 So when the user is seemingly tapping an input field, iOS interprets it as a tap on the background. 因此,当用户似乎点击输入字段时,iOS会将其解释为在背景上点击。

So I tried setting the new position and size but when I do that the animation doesn't play, it just snaps to the new position. 所以我尝试设置新的位置和大小但是当我这样做动画不播放时,它只是捕捉到新的位置。 Putting it before the addAnimation call and after it, with and without transactions, it doesn't make any difference. 将它放在addAnimation调用之前和之后,无论有没有事务,它都没有任何区别。

The delegate methods are still called, but you can't visually see any animation. 委托方法仍然被调用,但您无法直观地看到任何动画。

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];
}

I have found a way to make it work, can't say if it's the best way to do it but it seems to be working now. 我找到了一种方法使它工作,不能说它是否是最好的方法,但它似乎现在正在工作。

The key thing was to combine almost everything. 关键是要结合几乎所有东西。 So I had to keep removedOnCompletion and fillMode on my animations while also updating the position in my animationDidStop method. 所以我必须在动画上保留removedOnCompletionfillMode ,同时还要更新animationDidStop方法中的位置。 It works without setting the two animation parameters as well, but you can see a small flicker in the end. 它也可以在不设置两个动画参数的情况下工作,但最后你可以看到一个小的闪烁。

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

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM