Лучший способ вибрировать элемент пользовательского интерфейса? - PullRequest
6 голосов
/ 11 ноября 2009

Я пытаюсь вибрировать / встряхивать элемент пользовательского интерфейса, а именно элемент управления, как если бы он был поражен, и резонирует. Я могу использовать Core Animation, чтобы встряхнуть его вертикально, горизонтально или обоими на один пиксель:

CABasicAnimation* rotationXAnimation;
rotationXAnimation = [CABasicAnimation animationWithKeyPath:@"position.y"];
rotationXAnimation.fromValue = [NSNumber numberWithFloat: ((UIControl *) sender).center.y-1.0 ];
rotationXAnimation.toValue = [NSNumber numberWithFloat: ((UIControl *) sender).center.y+1.0 ];
rotationXAnimation.duration = 0.2;
rotationXAnimation.cumulative = NO; 
rotationXAnimation.repeatCount = 10.0; 
rotationXAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];

[((UIControl *) sender).layer addAnimation:rotationXAnimation forKey:@"upDownAnimation"];

Или я могу вращаться на небольшую дугу назад и вперед вокруг оси z (-M_PI * 0,02 и M_PI * 0,02):

CABasicAnimation* rotationAnimation;
rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
rotationAnimation.fromValue = [NSNumber numberWithFloat: -M_PI * 0.02 ];
rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI * 0.02 ];
rotationAnimation.duration = 0.2;
rotationAnimation.cumulative = NO;  
rotationAnimation.repeatCount = 10.0; 
rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];

[((UIControl *) sender).layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];

Ничто из этого не выглядит так приятно. У кого-нибудь есть хорошие альтернативы? Я был бы особенно признателен за отличные идеи keyPaths.

Спасибо!

Обновление:

Следующее, где я сокращаю и расширяю контроль, лучше, но я все еще ищу другие идеи.

CABasicAnimation* scaleAnimation;
scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
scaleAnimation.fromValue = [NSNumber numberWithFloat: 0.95 ];
scaleAnimation.toValue = [NSNumber numberWithFloat: +1.05 ];
scaleAnimation.duration = 0.1;
scaleAnimation.cumulative = NO; 
scaleAnimation.repeatCount = 10.0; 
scaleAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];

[((UIControl *) sender).layer addAnimation:scaleAnimation forKey:@"scaleAnimation"];

Ответы [ 3 ]

6 голосов
/ 25 октября 2010

Я встряхиваю один из моих видов ввода-ввода после неправильного ввода пользователя, используя:

- (void)earthquake:(UIView*)itemView
{
    CGFloat t = 2.0;
    CGAffineTransform leftQuake  = CGAffineTransformTranslate(CGAffineTransformIdentity, t, -t);
    CGAffineTransform rightQuake = CGAffineTransformTranslate(CGAffineTransformIdentity, -t, t);

    itemView.transform = leftQuake;  // starting point

    [UIView beginAnimations:@"earthquake" context:itemView];
    [UIView setAnimationRepeatAutoreverses:YES]; // important
    [UIView setAnimationRepeatCount:4];
    [UIView setAnimationDuration:0.07];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(earthquakeEnded:finished:context:)];

    itemView.transform = rightQuake; // end here & auto-reverse

    [UIView commitAnimations];
}

- (void)earthquakeEnded:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context 
{
    if ([finished boolValue]) 
    {
        UIView* item = (UIView *)context;
        item.transform = CGAffineTransformIdentity;
    }
}

Это выглядит вполне естественно, я получил этот код из какого-то интернет-потока, который я не могу вспомнить.

4 голосов
/ 11 ноября 2009

Вы можете использовать анимацию ключевого кадра в позиции слоя. Это субъективно, конечно, потому что я не уверен, что вы считаете "приятным". Анимация дрожания, которую вы получаете, когда вы неправильно вводите свой пароль OS X, я продублировал с помощью Core Animation в этом посте в блоге Cocoa Is My Girlfriend . Не уверен, что это то, что вы собираетесь, но это одна из альтернатив.

С уважением,

2 голосов
/ 24 февраля 2014

обновление * * * * * * Хороший маленький ответ Берсаелора, чтобы использовать UIView блочную анимацию вместо этого, некоторые люди не всегда знают, что вы можете использовать автореверс и повторный подсчет в этих:

self.transform = CGAffineTransformMakeTranslation(2.0, -2.0);
[UIView animateWithDuration:0.07
                      delay:0.0
                    options:UIViewAnimationOptionAutoreverse
                 animations:^{
                   UIView.animationRepeatCount = 4;
                   self.transform = CGAffineTransformMakeTranslation(-2.0, 2.0);
                 }
                 completion:^(BOOL finished){
                   self.transform = CGAffineTransformIdentity;
                 }];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...