mintuz
mintuz

Reputation: 721

UIButton limiting number of presses

I got an issue with users rapidly pressing my UIButton causing multiple entries being placed in my database stored online. I have tried all sorts such as hiding the button when it the action is called and some sort of toggle, both have been unsuccessful. Is there anyway to limit the press to just one. the action is linked to the touch up inside reference on the button.

-(IBAction)postData:(id)sender
{   

    if(loginControl == 0)
    {
    if(nameIB.text.length && numberIB.text.length > 0)
    {
        loginControl = 1;
        loginButton.hidden = YES;

        NSMutableData *data = [NSMutableData data]; 

        NSString *number = numberIB.text;
        NSString *name = nameIB.text;

        NSString *nameString = [[NSString alloc] initWithFormat:@"name=%@", name];
        NSString *numberString = [[NSString alloc] initWithFormat:@"&number=%@", number];
        NSString *genderString = [[NSString alloc] initWithFormat:@"&gender=%@", gender];

        //NSLog(nameString);
        //NSLog(numberString);

        [data appendData:[nameString dataUsingEncoding:NSUTF8StringEncoding]];
        [data appendData:[numberString dataUsingEncoding:NSUTF8StringEncoding]];
        [data appendData:[genderString dataUsingEncoding:NSUTF8StringEncoding]];

        NSURL *url = [NSURL URLWithString:@"http://www.blah.net/blah.php"];
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

        [request setHTTPMethod:@"POST"];
        [request setHTTPBody:data];

        NSURLResponse *response;
        NSError *err;
        NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
        NSLog(@"responseData: %@", responseData);

        userData = responseData;
        [self startParsingUserId];

        logoutButton.hidden = NO;
    }
    else {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Text Fields Empty" message:@"One Or More Textfields Are Empty" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:nil];
        [alert show];
        [alert release];

        loginControl = 0;
    }
    }

}

Upvotes: 0

Views: 175

Answers (2)

Alex Reynolds
Alex Reynolds

Reputation: 96966

In the button's selector, use -performSelectorOnMainThread:withObject:waitUntilDone: to run a chunk of code that disables the button until the method's logic is complete.

Upvotes: 0

Dave DeLong
Dave DeLong

Reputation: 243156

You should immediately be setting the enabled or hidden property of the button to disable interaction.

HOWEVER that change will not take effect until the next turn of the runloop, when everything gets re-drawn. As your code stands, your code is hiding the button, doing stuff, and then unhiding the button, all before the button gets a chance to redraw.

What you should do is set the hidden property and then start the computation (preferably on a background thread). Once and only once the computation completes, you should signal the main thread to un-hide the button again.

If you are OK with having this only work on iOS 4.0+, you can easily accomplish this with Grand Central Dispatch:

- (IBAction)doStuff:(id)sender {
  [button setEnabled:NO];
  dispatch_async(dispatch_get_global_queue(0,0), ^{

    // do all your computation/synchronous requesting here
    // this will happen on a background thread

    dispatch_async(dispatch_get_main_queue(), ^{
      [button setEnabled:YES];
    });
  });
}

Upvotes: 6

Related Questions