Свойства iOS UIView не анимируются с помощью CABasicAnimation - PullRequest
3 голосов
/ 10 января 2012

Я могу представить себе огромное количество вздохов, когда люди увидят этот вопрос всплывающим снова . Тем не менее, я прочитал много информации здесь, в документации и через Google, и до сих пор не нашел решения. Так что здесь ничего не идет.

Я пытаюсь воссоздать экран входа в Facebook, где расстояние и позиция анимируются с помощью клавиатуры, чтобы позволить пользователю по-прежнему видеть все поля ввода и кнопку входа.

Это работает, когда я использую kCAFillModeForwards и устанавливаю removedOnCompletion на NO. Но, как сказано в другом потоке на SO, кажется, что это только визуально меняет свойства, а фактическое положение касания не изменяется. Поэтому, когда пользователь, казалось бы, нажимает на поле ввода, 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 Ответ

2 голосов
/ 11 января 2012

Я нашел способ заставить это работать, не могу сказать, является ли это лучшим способом сделать это, но это, кажется, работает сейчас.

Ключевым моментом было объединить почти все. Поэтому мне пришлось сохранять removedOnCompletion и fillMode в моих анимациях, а также обновлять позицию в моем методе 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"];

}

...