schwabr
schwabr

Reputation:

iPhone How To: UIButtons That Disappear One By One at Set Interval

I am creating a quiz game and I can't figure out the best way to implement UIButtons that disappear one by one at 3 second intervals. I can get the first UIButton to disappear after 3 seconds, but the subsequent UIButtons take considerably longer.

I believe the problem is that my code becomes more inefficient with each UIButton I make disappear. The following method is what I call with a repeating NSInterval to make each subsequent UIButton disappear:

-(void)hideButton { int buttonNum;

while(buttonNum != -1)
{
    buttonNum = rand() % 5;

    if(buttonNum != [quiz correctNumber])
    {
        if(buttonNum == 0 && [buttonOne isEnabled] == YES)
        {
            [UIView beginAnimations:@"buttonFades" context:nil];
            [UIView setAnimationDuration:0.5];
            [buttonOne setEnabled:NO];
            [buttonOne setAlpha:0.0];
            [UIView commitAnimations];
        }
        else if(buttonNum == 1 && [buttonTwo isEnabled] == YES)
        {
            [UIView beginAnimations:@"buttonFades" context:nil];
            [UIView setAnimationDuration:0.5];
            [buttonTwo setEnabled:NO];
            [buttonTwo setAlpha:0.0];
            [UIView commitAnimations];
        }
        else if(buttonNum == 2 && [buttonThree isEnabled] == YES)
        {
            [UIView beginAnimations:@"buttonFades" context:nil];
            [UIView setAnimationDuration:0.5];
            [buttonThree setEnabled:NO];
            [buttonThree setAlpha:0.0];
            [UIView commitAnimations];
        }
        else if(buttonNum == 3 && [buttonFour isEnabled] == YES)
        {
            [UIView beginAnimations:@"buttonFades" context:nil];
            [UIView setAnimationDuration:0.5];
            [buttonFour setEnabled:NO];
            [buttonFour setAlpha:0.0];
            [UIView commitAnimations];
        }
        else if(buttonNum == 4 && [buttonFive isEnabled] == YES)
        {
            [UIView beginAnimations:@"buttonFades" context:nil];
            [UIView setAnimationDuration:0.5];
            [buttonFive setEnabled:NO];
            [buttonFive setAlpha:0.0];
            [UIView commitAnimations];
        }

        buttonNum = -1;
    }
}

}

Upvotes: 1

Views: 2613

Answers (3)

Amagrammer
Amagrammer

Reputation: 6373

Good answer from Alex Martelli. Another possibility would be to replace the separate objects buttonOne, buttonTwo, etc. with a single array of buttons, button[5] and replace your big loop with this:

do {
   buttonNum = rand() % 5;
} while (buttonNum == [quiz correctNumber] || ![buttons[buttonNum] isEnabled]);

[buttons[buttonNum] setEnabled:NO]; // Doesn't need to be in animation block
[UIView beginAnimations:@"buttonFades" context:nil];
[UIView setAnimationDuration:0.5];
[buttons[buttonNum] setAlpha:0.0];
[UIView commitAnimations];

*** Dan, below: Something to randomize the order of the button hiding and make sure the correct answer was not hidden would still be needed, but otherwise that's a great solution too.

Upvotes: 1

Dan Lorenc
Dan Lorenc

Reputation: 5394

Another way of making the buttons disappear at set intervals is to use the

- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay

method. To use this, you would define a function to make a button disappear when it is called:

-(void)hideButton:(UIButton *)button{
button.enabled = NO;
[UIView beginAnimations:@"buttonFades" context:nil];
[UIView setAnimationDuration:0.5];
[button setAlpha:0.0];
[UIView commitAnimations];
}

Then you would spit out those delayed selectors in a loop like this:

for(int i=0; i<numButtons; i++){
    [self performSelector:@selector(mySelector:) withObject:buttons[i] afterDelay:3*i+3]
}

Upvotes: 1

Alex Martelli
Alex Martelli

Reputation: 882103

When you have only, say, 2 buttons left, since you still generate a random number between 0 and 4, you only have a 20% chance of actually making one more button disappear -- 20% of the time you'll do nothing because the random number matches the correct one, and 60% of the time under those conditions you'll do nothing because it matches an already-disappeared button.

I suggest you keep an array initially populated with references the 4 buttons that may actually disappear (don't bother putting the correct-number one there as you'll never disappear it anyway). In your function, generate a random number that's between 0 and N-1 when you have N buttons left in that array, so you can disappear the appropriate button with effective and concise code -- then (if the button that disappeared was not the last one in the array) swap it with the last one and decrement N by one. Of course when N is 1 there's no need for the random number either.

Upvotes: 3

Related Questions