Encapsulation and state management are very useful for situations like this. Depending on how much you wish to encapsulate, you might consider having a new object to be modified by the UIButton (you mention Play/Pause so I'm imagining some kind of media player?)
(You might consider an enumeration
of states in this example to make it more extendable, but for simplicity I'll use a BOOL
)
@interface MediaManager : NSObject
{
BOOL isPlaying; // whether
NSTimer *playTimer; // timer used exclusively by the media manager
//... other vars relating to type of media/selected track etc anything related
}
-(void) togglePlay;
@property (nonatomic, synthesize) NSTimer *playTimer;
@propety (nonatomic, assign) BOOL isPlaying;
@end
@implementation MediaManager
@synthesize playTier, isPlaying;
- (void)togglePlay
{
if (!self.isPlaying)
{
if (self.playTimer == nil) // if it hasn't already been assigned
{
self.playTimer = [NSTimer ...]; // create and schedule the timer
self.isPlaying = YES;
}
}
else
{
if (self.playTimer != nil)
{
// get the timer and invalidate it
self.isPlaying = NO;
}
}
}
@end
This is not the best though out example, but by encapsulating the state within a seperate object, your view UIButton
can rely solely on the model state for presenting itself (assuming it holds a reference to an initialized Media Manager
:
-(IBAction) buttonPressed: (id) sender
{
[self.mediaManager togglePlay]; // play from whatever state it is in
// update the button text to reflect state
if (self.mediaManager isPlaying)
{
self.mediaButton.textLabel.text = @"Pause";
}
else
{
self.mediaButton.textLabel.text = @"Play";
}
}
This way you don't have to include the state handling each time you want to use this functionality, and the button always reflects the true state of the object it is acting on.
You might go a step further and encapsulate the state strings in the object also, which could be queried in a similar manner.
(Apologies for poorly written code, I've not had a coffee yet)