Сделать эффект встряхивания для ярлыка в ios?

Я работаю с эффектом встряхивания для метки, я вызвал анимацию при нажатии ячейки в tableview, но она не работает. Если я вызываю анимацию в cellForRowAtIndexPath: (NSIndexPath *) indexPath, она работает, но если я вызываю ее в didSelectRowAtIndexPath: (NSIndexPath *) indexPath это не работает. может кто-нибудь мне помочь ??? заранее спасибо

   -(void)shakeAnimation:(UILabel*) label {
    const int reset = 5;
    const int maxShakes = 6;

    //pass these as variables instead of statics or class variables if shaking two controls simultaneously
    static int shakes = 0;
    static int translate = reset;

    [UIView animateWithDuration:0.09-(shakes*.01) // reduce duration every shake from .09 to .04
                          delay:0.01f//edge wait delay
                        options:(enum UIViewAnimationOptions) UIViewAnimationCurveEaseInOut
                     animations:^{label.transform = CGAffineTransformMakeTranslation(translate, 0);}
                     completion:^(BOOL finished){
                         if(shakes < maxShakes){
                             shakes++;

                             //throttle down movement
                             if (translate>0)
                                 translate--;

                             //change direction
                             translate*=-1;
                             [self shakeAnimation:label];
                         } else {
                             label.transform = CGAffineTransformIdentity;
                             shakes = 0;//ready for next time
                             translate = reset;//ready for next time
                             return;
                         }
                     }];
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    [self shakeAnimation:cell.MyHomeMenuCountlabel];

}

person Vijay    schedule 13.08.2013    source источник
comment
Определить не работает. А где вы получаете cell в своем didSelectRowAtIndexPath методе?   -  person rmaddy    schedule 13.08.2013
comment
@maddy не может тебя достать ???   -  person Vijay    schedule 13.08.2013
comment
Я создал пользовательскую ячейку и просто применил к ней анимацию   -  person Vijay    schedule 13.08.2013
comment
В вашем методе didSelectRowAtIndexPath есть ссылка на переменную с именем cell. Откуда эта переменная? И пожалуйста, поясните, что вы имеете в виду под словом «не работать»? Вы получаете ошибку компиляции, ошибку времени выполнения или что-то просто работает не так, как ожидалось?   -  person rmaddy    schedule 13.08.2013
comment
он работает нормально, но я хочу встряхнуть, когда строка выбрана, как это сделать ??   -  person Vijay    schedule 13.08.2013
comment
Да, я это понимаю. Но вы не объяснили, что происходит, когда вы пытаетесь встряхнуть этикетку при выделении строки. Расскажите, что происходит? Вы получаете ошибку компиляции, ошибку времени выполнения или что-то просто работает не так, как ожидалось?   -  person rmaddy    schedule 13.08.2013
comment
нет ошибок ничего не происходит пока я нажимаю анимацию не применяется   -  person Vijay    schedule 13.08.2013
comment
позвольте нам продолжить обсуждение в чате   -  person Vijay    schedule 13.08.2013
comment
добавить свой собственный код ячейки?   -  person NANNAV    schedule 13.08.2013


Ответы (4)


Это можно сделать двумя способами:

1. Попробуйте эту функцию:

NSArray *arrIndexPath = [NSArray arrayWithObject:indexPath];
[dropTable reloadRowsAtIndexPaths:arrIndexPath withRowAnimation:UITableViewRowAnimationFade];

в функции didSelectRowAtIndexPath.

Делать анимацию только в cellForRowAtIndexPath.

2. Назначьте свойство тега вашей ячейке в cellForRowAtIndexPath.

cell.tag = indexPath.row.

В didSelectRowAtIndexPath:

Затем, используя subviews таблицы, получите cell.tag, равный indexPath.row, и взяв ссылку на ту же ячейку, а затем выполните анимацию:

for (MyHomeViewCell *cell in [table subviews]) { // change name of table here 
  if ([cell isKindOfClass:[MyHomeViewCell class]]) { 
    if (cell.tag == indexPath.row) { 
        [self shakeAnimation:cell.MyHomeMenuCountlabel]; 
    } 
  } 
}
person Samkit Jain    schedule 13.08.2013
comment
Объект вашей настраиваемой ячейки, затем напишите cell.tag = indexPath.row в cellForRowAtIndexPath - person Samkit Jain; 13.08.2013
comment
он работает, но если я нажимаю первую строку, это означает, что только она трясется, и примечательно, что все строки трясутся - person Vijay; 13.08.2013
comment
Вы можете подробнее описать то, что говорите? - person Samkit Jain; 13.08.2013
comment
позвольте нам продолжить обсуждение в чате - person Vijay; 13.08.2013

используйте этот код для анимации встряхивания для представлений

-(void)shakeAnimation:(UILabel*) label
 {
        CABasicAnimation *shake = [CABasicAnimation animationWithKeyPath:@"position"];
        [shake setDuration:0.1];
        [shake setRepeatCount:5];
        [shake setAutoreverses:YES];
        [shake setFromValue:[NSValue valueWithCGPoint:
                             CGPointMake(label.center.x - 5,label.center.y)]];
        [shake setToValue:[NSValue valueWithCGPoint:
                           CGPointMake(label.center.x + 5, label.center.y)]];
        [label.layer addAnimation:shake forKey:@"position"];
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    UITableViewCell cell = [theTableView cellForRowAtIndexPath:theIndexPath]; 
UILabel label=(UILabel*)[cell.contentView viewWithTag:2001];
[self shakeAnimation:label];

}
person NANNAV    schedule 13.08.2013
comment
он работает нормально, но я хочу встряхнуть, когда строка выбрана, как это сделать ?? - person Vijay; 13.08.2013
comment
вы получаете доступ к выбранной ячейке и получаете доступ к uilabel в ячейке с помощью тега, подобного этому UITableViewCell cell = [theTableView cellForRowAtIndexPath: theIndexPath]; UILabel label = (UILabel *) [cell.contentView viewWithTag: 2001]; [self shakeAnimation: label]; - person NANNAV; 13.08.2013
comment
Я создал настраиваемую ячейку с метками, каждая строка будет иметь одну метку - person Vijay; 13.08.2013

Финли, у меня есть решение, надеюсь, оно вам поможет. Для встряхивания конкретной метки вы можете добавить UITapGestureRecognizer для получения конкретного касания UILabel и установить анимацию встряхивания в метод UITapGestureRecognizer @selector, как в примере Bellow: -

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }

    UILabel *cellTitle=[[UILabel alloc]initWithFrame:CGRectMake(100, 7, 300, 30)];
    cellTitle.userInteractionEnabled = YES;
    cellTitle.tag = indexPath.section;
    [cellTitle setBackgroundColor:[UIColor clearColor]];
    [cellTitle setFont:[UIFont fontWithName:@"Helvetica" size:14]];
    [cellTitle setText:_objects[indexPath.row]];
    [cellTitle setTextColor:[UIColor blackColor]];
    [cell.contentView addSubview:cellTitle];


    UITapGestureRecognizer *labelTap = [[UITapGestureRecognizer alloc] init];
    [labelTap addTarget:self action:@selector(viewPatient:)];
    [labelTap setDelegate:nil];
    [labelTap setNumberOfTapsRequired:1];
    [cellTitle addGestureRecognizer:labelTap]; // cellTitle add here
    [labelTap release];
    return cell;
}



-(void)viewPatient:(id)sender
{

    UILabel *lObjLabel = (UILabel *)[sender view];

    CGFloat t = 2.0;
    CGAffineTransform translateRight  = CGAffineTransformTranslate(CGAffineTransformIdentity, t, 0.0);
    CGAffineTransform translateLeft = CGAffineTransformTranslate(CGAffineTransformIdentity, -t, 0.0);

    lObjLabel.transform = translateLeft;

    [UIView animateWithDuration:0.07 delay:0.0 options:UIViewAnimationOptionAutoreverse|UIViewAnimationOptionRepeat animations:^{

        [UIView setAnimationRepeatCount:10];
        lObjLabel.transform = translateRight;
    } completion:^(BOOL finished) {

        if (finished) {
            [UIView animateWithDuration:0.05 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
                lObjLabel.transform = CGAffineTransformIdentity;
            } completion:NULL];


        }
    }];
}

Этот код работает так: -

введите описание изображения здесь

person Nitin Gohel    schedule 13.08.2013
comment
Начиная с iOS 4.0 использование этих методов анимации не рекомендуется. Вместо этого вам действительно следует использовать методы блочной анимации. - person rmaddy; 13.08.2013
comment
Мне просто интересно, почему никто не хочет использовать блочную анимацию, как Apple рекомендует и поощряет разработчиков на iOS4 и выше? - person holex; 13.08.2013

используйте эту функцию - (void) shakeView: (UIView *) viewToShake и запишите любой код анимации, который вы хотите в этой функции, и вызовите его из того места, где вы хотите оживить свой элемент

и если вы выберете первую анимацию, тогда также используйте следующий фрагмент кода, эта функция используется для правильного завершения анимации

#define RADIANS(degrees) ((degrees * M_PI) / 180.0)

- (void) wobbleEnded:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{
UIView* item = (__bridge UIView *)context;
item.transform = CGAffineTransformRotate(CGAffineTransformIdentity, RADIANS(90.0));
}

и вот два типа анимации, выберите все, что вы хотите


1. встряхните анимацию, как удаление pp с ipad или iphone, и решите встряхнуть под правильным углом

CGAffineTransform leftWobble = CGAffineTransformRotate(CGAffineTransformIdentity, RADIANS(88.0));
CGAffineTransform rightWobble = CGAffineTransformRotate(CGAffineTransformIdentity, RADIANS(92.0));

viewToShake.transform = leftWobble;  // starting point

[UIView beginAnimations:@"wobble" context:(__bridge void *)(viewToShake)];
[UIView setAnimationRepeatAutoreverses:YES]; // important
[UIView setAnimationRepeatCount:2000];
[UIView setAnimationDuration:0.25];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(wobbleEnded:finished:context:)];

viewToShake.transform = rightWobble; // end here & auto-reverse

[UIView commitAnimations];

2. нормальная анимация встряхивания

CGFloat t = 2.0;
CGAffineTransform translateRight  = CGAffineTransformTranslate(CGAffineTransformIdentity, 85, 0.0);
CGAffineTransform translateLeft = CGAffineTransformTranslate(CGAffineTransformIdentity, 95, 0.0);

viewToShake.transform = translateLeft;

[UIView animateWithDuration:0.07 delay:0.0 options:UIViewAnimationOptionAutoreverse|UIViewAnimationOptionRepeat animations:^{
    [UIView setAnimationRepeatCount:2.0];
    viewToShake.transform = translateRight;
} completion:^(BOOL finished) {
    if (finished) {
        [UIView animateWithDuration:0.05 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
            viewToShake.transform = CGAffineTransformTranslate(CGAffineTransformIdentity, 95, 0.0);
        } completion:NULL];
    }
}];

}

person Anurag Soni    schedule 13.08.2013