Skip to content

Instantly share code, notes, and snippets.

@hollance
Created November 28, 2012 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hollance/4161532 to your computer and use it in GitHub Desktop.
Save hollance/4161532 to your computer and use it in GitHub Desktop.
@implementation MHButton
{
BOOL observing; // whether we're listening to changes in state
BOOL didDrawHighlighted; // used to optimize drawing
BOOL didDrawEnabled; // used to optimize drawing
}
@synthesize appearance;
- (void)setAppearance:(id <MHButtonAppearance>)newAppearance
{
if (appearance != newAppearance)
{
appearance = newAppearance;
if (!observing)
{
[self addObserver:self forKeyPath:@"highlighted" options:NSKeyValueObservingOptionNew context:NULL];
[self addObserver:self forKeyPath:@"enabled" options:NSKeyValueObservingOptionNew context:NULL];
observing = YES;
}
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
BOOL changed = NO;
BOOL newState = [[change objectForKey:NSKeyValueChangeNewKey] intValue];
// We'll receive a lot of notifications but we only want to redraw when the
// state actually did change. (Observing these properties works better than
// overriding touches on the button.)
if ([keyPath isEqualToString:@"highlighted"])
changed = (newState != didDrawHighlighted);
else if ([keyPath isEqualToString:@"enabled"])
changed = (newState != didDrawEnabled);
if (changed)
[self setNeedsDisplay];
}
- (void)dealloc
{
if (observing)
{
[self removeObserver:self forKeyPath:@"highlighted"];
[self removeObserver:self forKeyPath:@"enabled"];
}
}
- (void)drawRect:(CGRect)rect
{
if (self.appearance != nil)
{
CGContextRef context = UIGraphicsGetCurrentContext();
[self.appearance button:self drawRect:rect inContext:context];
}
didDrawHighlighted = self.highlighted;
didDrawEnabled = self.enabled;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment