Reputation: 721
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
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
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