How to deal with a Toggle NSButton?
My application contains a PLAY/PAUSE button that is set to type Toggle in Interface Builder. I use it - as the name reveals - to play back my assets or to pause them.
Further, I am listening to the SPACE key to enable the same functionality via the keyboard shortcut. Therefore, I usekeyDown:
from NSResponder
in my application. This is done in another subview开发者_如何学C. The button itself is not visible at this time.
I store the current state of playback in a Singleton.
How would you update the title/alternative title for the toogle button while taking into account that its state could have been altered by the keyboard shortcut? Can I use bindings?
I managed to implement the continuous update of the button title as follows. I added a programmatic binding for the state (in the example buttonTitle
). Notice, that the IBAction
toggleButtonTitle:
does not directly change the button title! Instead the updateButtonTitle
method is responsible for this task. Since self.setButtonTitle
is called the aforementioned binding gets updated immediately.
The following example shows what I tried to describe.
// BindThisAppDelegate.h
#import <Cocoa/Cocoa.h>
@interface BindThisAppDelegate : NSObject<NSApplicationDelegate> {
NSWindow* m_window;
NSButton* m_button;
NSString* m_buttonTitle;
NSUInteger m_hitCount;
}
@property (readwrite, assign) IBOutlet NSWindow* window;
@property (readwrite, assign) IBOutlet NSButton* button;
@property (readwrite, assign) NSString* buttonTitle;
- (IBAction)toggleButtonTitle:(id)sender;
@end
And the implementation file:
// BindThisAppDelegate.m
#import "BindThisAppDelegate.h"
@interface BindThisAppDelegate()
- (void)updateButtonTitle;
@end
@implementation BindThisAppDelegate
- (id)init {
self = [super init];
if (self) {
m_hitCount = 0;
[self updateButtonTitle];
}
return self;
}
@synthesize window = m_window;
@synthesize button = m_button;
@synthesize buttonTitle = m_buttonTitle;
- (void)applicationDidFinishLaunching:(NSNotification*)notification {
[self.button bind:@"title" toObject:self withKeyPath:@"buttonTitle" options:nil];
}
- (IBAction)toggleButtonTitle:(id)sender {
m_hitCount++;
[self updateButtonTitle];
}
- (void)updateButtonTitle {
self.buttonTitle = (m_hitCount % 2 == 0) ? @"Even" : @"Uneven";
}
@end
If you store your state in an enum or integer a custom NSValueTransformer
will help you to translate a state into its button title equivalent. You can add the NSValueTransformer
to the binding options.
NSDictionary* options = [NSDictionary dictionaryWithObject:[[CustomValueTransformer alloc] init] forKey:NSValueTransformerBindingOption];
[self.button bind:@"title" toObject:self withKeyPath:@"buttonTitle" options:options];
精彩评论