forked from ReactiveCocoa/ReactiveCocoa
-
Notifications
You must be signed in to change notification settings - Fork 0
/
NSControl+RACCommandSupport.m
59 lines (45 loc) · 1.83 KB
/
NSControl+RACCommandSupport.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
//
// NSControl+RACCommandSupport.m
// ReactiveCocoa
//
// Created by Josh Abernathy on 3/3/12.
// Copyright (c) 2012 GitHub, Inc. All rights reserved.
//
#import "NSControl+RACCommandSupport.h"
#import "EXTScope.h"
#import "NSObject+RACPropertySubscribing.h"
#import "RACCommand.h"
#import "RACScopedDisposable.h"
#import "RACSignal+Operations.h"
#import <objc/runtime.h>
static void *NSControlRACCommandKey = &NSControlRACCommandKey;
static void *NSControlEnabledDisposableKey = &NSControlEnabledDisposableKey;
@implementation NSControl (RACCommandSupport)
- (RACCommand *)rac_command {
return objc_getAssociatedObject(self, NSControlRACCommandKey);
}
- (void)setRac_command:(RACCommand *)command {
objc_setAssociatedObject(self, NSControlRACCommandKey, command, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
// Tear down any previous binding before setting up our new one, or else we
// might get assertion failures.
[objc_getAssociatedObject(self, NSControlEnabledDisposableKey) dispose];
objc_setAssociatedObject(self, NSControlEnabledDisposableKey, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
if (command == nil) {
self.enabled = YES;
return;
}
[self rac_hijackActionAndTargetIfNeeded];
RACScopedDisposable *disposable = [[command.enabled setKeyPath:@"enabled" onObject:self] asScopedDisposable];
objc_setAssociatedObject(self, NSControlEnabledDisposableKey, disposable, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (void)rac_hijackActionAndTargetIfNeeded {
SEL hijackSelector = @selector(rac_commandPerformAction:);
if (self.target == self && self.action == hijackSelector) return;
if (self.target != nil) NSLog(@"WARNING: NSControl.rac_command hijacks the control's existing target and action.");
self.target = self;
self.action = hijackSelector;
}
- (void)rac_commandPerformAction:(id)sender {
[self.rac_command execute:sender];
}
@end