views:

2956

answers:

1

After my user clicks a button, I'd like that button to stay pushed during the time that I perform a network operation. When the network operation is complete, I want the button to return to its default state.

I've tried calling -[UIButton setSelected:YES] right after the button push (with a corresponding call to -[UIButton setSelected:NO] after my network op finishes) but it doesn't seem to do anything. Same thing if I call setHighlighted:.

I suppose I could try swapping out the background image to denote a selected state for the duration of the network op...but that seems like a hack. Any better suggestions?

Here's what my code looks like...

- (IBAction)checkInButtonPushed
{
    self.checkInButton.enabled = NO;
    self.checkInButton.selected = YES;
    self.checkInButton.highlighted = YES;
    [self.checkInActivityIndicatorView startAnimating];
    [CheckInOperation startWithPlace:self.place delegate:self];
}

- (void)checkInCompletedWithNewFeedItem:(FeedItem*)newFeedItem wasNewPlace:(BOOL)newPlace possibleError:(NSError*)error;
{
    [self.checkInActivityIndicatorView stopAnimating];
    self.checkInButton.enabled = YES;
    self.checkInButton.selected = NO;
    self.checkInButton.highlighted = NO;
}
+5  A: 

How are you setting the images for the different UIControlStates on the button? Are you setting a background image for UIControlStateHighlighted as well as UIControlStateSelected?

UIImage *someImage = [UIImage imageNamed:@"SomeResource.png"];
[button setBackgroundImage:someImage forState:UIControlStateHighlighted];
[button setBackgroundImage:someImage forState:UIControlStateSelected];

If you're setting the selected state on the button touch down event rather than touch up inside, your button will actually be in a highlighted+selected state, so you'll want to set that too.

[button setBackgroundImage:someImage forState:(UIControlStateHighlighted|UIControlStateSelected];

Edit:

To sum up my remarks in the comments and to address the code you posted...you need to set your background images for the full UIControl state that you're in. According to your code snippet, this control state would be disabled+selected+highlighted for the duration of the network operation. This means that you would need to do this:

[button setBackgroundImage:someImage forState:(UIControlStateDisabled|UIControlStateHighlighted|UIControlStateSelected];

If you remove the highlighted = YES, then you would need this:

[button setBackgroundImage:someImage forState:(UIControlStateDisabled|UIControlStateSelected];

Get the picture?

Sbrocket
In effect, I believe I'm doing what you suggest; I'm just doing it through Interface Builder. I added the code I'm using to my question above...perhaps that would shed some light on the problem?The behavior I want is that I want the button to stay selected through the duration of my network operation. What I'm seeing is that the button highlights when touched, then the highlight goes away when the touch is done. The button -never- gets selected.Why this wouldn't work makes no sense to me, so I feel like I'm doing something stupid. I've checked all my IB connections and they're good...
Greg Maletic
I don't believe you can set a background image for the highlighted+selected state in Interface Builder, only the highlighted and selected states separately. If your button was in a state such that highlighted and selected were both set, I believe it would default to your normal image, not either of the highlighted or selected images. From your code, you're setting the state of the button such that both selected and highlighted are YES. Is checkInButtonPushed connected to "Touch Up Inside" or something else?
Sbrocket
Yes, it is connected to "Touch Up Inside". And if I remove the code related to the 'highlighted' state, it still doesn't work. The 'selected' state never gets shown.
Greg Maletic
Also, why are you disabling the button? That would actually mean that the button state is disabled+highlighted+selected. If you removed the line setting highlighted to YES, then you have disabled+selected, so you need to set an image for the (UIControlStateDisabled|UIControlStateSelected) state.
Sbrocket
Okay, that was the problem. When I took out the disable functionality, it worked as expected. Thanks!(To answer your question, I'm disabling the button because I don't want anyone pushing it again while the network operation is going on.)
Greg Maletic
You can certainly keep disabling the button, and you can even keep setting highlighted to YES as well - you just need to make sure that you set a background image for the proper control state of the button if you want to do so.
Sbrocket