wh1t3cat1k
wh1t3cat1k

Reputation: 3186

Animating the selection of UIButton

Good Moscow evening to everyone!

I'm still unfamiliar with principles of iPhone animation (btw, does anybody know a big and nice tutorial on this?), but in my project I want to do button "highlighted-not highlighted" flicker to notify the user that its label has changed.

This code doesn't do anything (it's just a fragment of flicker animation):

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration: 0.5]; 

[button setHighlighted: YES];

[UIView commitAnimations];

And this one highlights the button, but does not do it in an animated form:

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration: 0.5]; 

[button setSelected: YES];

[UIView commitAnimations];

Can anyone help me and say:

  1. What's wrong with this code?
  2. What would fix the problem?

----------------------------------- UPDATE ------------------------------

I tried that kind of code, but it doesn't work either:

// ------------------------
// --- animation ----------
// ------------------------

- (void)animateIn
{
[UIView beginAnimations: @"animateIn" context:nil]; 
[UIView setAnimationDuration: 0.2];

[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)]; 

[control setBackgroundColor:[UIColor blackColor]];

[UIView commitAnimations];
}

- (void)animateOut
{
[UIView beginAnimations: @"animateOut" context:nil];    
[UIView setAnimationDuration: 0.2];

[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)]; 

[control setBackgroundColor:[UIColor whiteColor]];

[UIView commitAnimations];
}


- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{
if([animationID isEqualToString: @"animateIn"])
{
    [self animateOut];
    return;
}
else if ([animationID isEqualToString: @"animateOut"])
{
    cycleCount++;

    if(cycleCount < 3)
        [self animateIn];
    else
        cycleCount = 0;

    return;
}
}

@end

Upvotes: 1

Views: 1605

Answers (3)

Daddy
Daddy

Reputation: 9035

//isFlickerOn is declared in .h file as BOOL isFlickerOn;
//flickerTimer is declared in .h file as NSTimer *flickerTimer;
//flickerCount is declared in .h file as int flickerCount; 
//control is a UILabel, UIButton background color is really hard to notice
//especially the roundedRect UIButton, so I just flickered a UILabel's textColor

-(void)flickerOn {
    if (flickerCount < 5) 
    {
    flickerCount++;
         if (!isFlickerOn)
        {
            [control setTextColor:[UIColor yellowColor]];
            isFlickerOn = YES;
        } 
        else
        {
            [control setTextColor:[UIColor blueColor]];
            isFlickerOn = NO;   
        }
    }
    else 
    {
        [flickerTimer invalidate];
    }
}


-(void)flickerAnimation {
    flickerCount = 0;
    flickerTimer = [NSTimer scheduledTimerWithTimeInterval:0.3f target:self selector:@selector(flickerOn) userInfo:nil repeats:YES];
}

Upvotes: 2

Daddy
Daddy

Reputation: 9035

You need to create a callback method that executes when the first animation finishes. You use that callback to do create a deselected animation. Keep in mind that there is no gradual "selection state" like there is for transparency. You have to use the

[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
[UIView beginAnimations:@"animateIn" context:NULL];

From Apple's docs:

- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {

Your method must take the following arguments:

animationID

An NSString containing an optional application-supplied identifier. This is the identifier that is passed to the beginAnimations:context: method. This argument can be nil.

finished

An NSNumber object containing a Boolean value. The value is YES if the animation ran to completion before it stopped or NO if it did not.

context

An optional application-supplied context. This is the context data passed to the beginAnimations:context: method. This argument can be nil.

When the animation is finished, the callback animationDidStop is called and passed in the string @"animateIn". You can use that method to check which animation was called and handle that there.

Upvotes: 1

Brad
Brad

Reputation: 11515

Not all attributes of a UIView are animatable - and I do not believe "highlighted" or "selected" are.

Typically, it's usable for non-boolean values, like "center", "alpha", "frame" and "bounds".

Try tweaking the alpha instead, and you'll see it will work.

Upvotes: 1

Related Questions