Skip to content
Browse files

Merge pull request #406 from KyleLeneau/uibarbutton_command_support

Adding UIBarButtonItem RACCommand Support.
  • Loading branch information...
2 parents cc4ff70 + 929c824 commit daa9f2a60dcd7f695dcb6615576711fafcc549e4 @joshaber joshaber committed Apr 9, 2013
View
8 ReactiveCocoaFramework/ReactiveCocoa.xcodeproj/project.pbxproj
@@ -7,6 +7,8 @@
objects = {
/* Begin PBXBuildFile section */
+ 27A887D11703DC6800040001 /* UIBarButtonItem+RACCommandSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 27A887C81703DB4F00040001 /* UIBarButtonItem+RACCommandSupport.m */; };
+ 27A887D21703DDEB00040001 /* UIBarButtonItem+RACCommandSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 27A887C71703DB4F00040001 /* UIBarButtonItem+RACCommandSupport.h */; settings = {ATTRIBUTES = (Public, ); }; };
5F244771167E5EDE0062180C /* RACPropertySubject.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F24476F167E5EDE0062180C /* RACPropertySubject.h */; settings = {ATTRIBUTES = (Public, ); }; };
5F244772167E5EDE0062180C /* RACPropertySubject.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F24476F167E5EDE0062180C /* RACPropertySubject.h */; settings = {ATTRIBUTES = (Public, ); }; };
5F244773167E5EDE0062180C /* RACPropertySubject.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F244770167E5EDE0062180C /* RACPropertySubject.m */; };
@@ -358,6 +360,8 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
+ 27A887C71703DB4F00040001 /* UIBarButtonItem+RACCommandSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIBarButtonItem+RACCommandSupport.h"; sourceTree = "<group>"; };
+ 27A887C81703DB4F00040001 /* UIBarButtonItem+RACCommandSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIBarButtonItem+RACCommandSupport.m"; sourceTree = "<group>"; };
5F24476F167E5EDE0062180C /* RACPropertySubject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACPropertySubject.h; sourceTree = "<group>"; };
5F244770167E5EDE0062180C /* RACPropertySubject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACPropertySubject.m; sourceTree = "<group>"; };
5F2447AC167E87C50062180C /* RACObservablePropertySubjectSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACObservablePropertySubjectSpec.m; sourceTree = "<group>"; };
@@ -891,6 +895,8 @@
88F44265153DCAC50097B4C3 /* UITextField+RACSignalSupport.m */,
A1FCC27215666AA3008C9686 /* UITextView+RACSignalSupport.h */,
A1FCC27315666AA3008C9686 /* UITextView+RACSignalSupport.m */,
+ 27A887C71703DB4F00040001 /* UIBarButtonItem+RACCommandSupport.h */,
+ 27A887C81703DB4F00040001 /* UIBarButtonItem+RACCommandSupport.m */,
);
name = "UIKit Support";
sourceTree = "<group>";
@@ -1183,6 +1189,7 @@
D077A16E169B740200057BB1 /* RACEvent.h in Headers */,
D099E819169E05D00000A975 /* NSObject+RACObservablePropertySubject.h in Headers */,
6EA0C08216F4AEC1006EBEB2 /* NSObject+RACDeallocating.h in Headers */,
+ 27A887D21703DDEB00040001 /* UIBarButtonItem+RACCommandSupport.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1490,6 +1497,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 27A887D11703DC6800040001 /* UIBarButtonItem+RACCommandSupport.m in Sources */,
8882D4601673B0450080E7CD /* RACBlockTrampoline.m in Sources */,
88F440BA153DAD570097B4C3 /* RACCommand.m in Sources */,
88F440B7153DAD320097B4C3 /* RACSwizzling.m in Sources */,
View
1 ReactiveCocoaFramework/ReactiveCocoa/ReactiveCocoa.h
@@ -45,6 +45,7 @@
#import <ReactiveCocoa/UIControl+RACSignalSupport.h>
#import <ReactiveCocoa/UITextField+RACSignalSupport.h>
#import <ReactiveCocoa/UITextView+RACSignalSupport.h>
+#import <ReactiveCocoa/UIBarButtonItem+RACCommandSupport.h>
#elif TARGET_OS_MAC
#import <ReactiveCocoa/EXTKeyPathCoding.h>
#import <ReactiveCocoa/NSControl+RACCommandSupport.h>
View
22 ReactiveCocoaFramework/ReactiveCocoa/UIBarButtonItem+RACCommandSupport.h
@@ -0,0 +1,22 @@
+//
+// UIBarButtonItem+RACCommandSupport.h
+// ReactiveCocoa
+//
+// Created by Kyle LeNeau on 3/27/13.
+// Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+@class RACCommand;
+
+@interface UIBarButtonItem (RACCommandSupport)
+
+// Sets the control's command. When the control is clicked, the command is
+// executed with the sender of the event. The control's enabledness is bound
+// to the command's `canExecute`.
+//
+// Note: this will reset the control's target and action.
+@property (nonatomic, strong) RACCommand *rac_command;
+
+@end
View
56 ReactiveCocoaFramework/ReactiveCocoa/UIBarButtonItem+RACCommandSupport.m
@@ -0,0 +1,56 @@
+//
+// UIBarButtonItem+RACCommandSupport.m
+// ReactiveCocoa
+//
+// Created by Kyle LeNeau on 3/27/13.
+// Copyright (c) 2013 GitHub, Inc. All rights reserved.
+//
+
+#import "UIBarButtonItem+RACCommandSupport.h"
+#import <ReactiveCocoa/RACCommand.h>
+#import <ReactiveCocoa/RACSubscriptingAssignmentTrampoline.h>
+#import <ReactiveCocoa/NSObject+RACPropertySubscribing.h>
+#import <ReactiveCocoa/RACSignal+Operations.h>
+#import <ReactiveCocoa/RACDisposable.h>
+#import <ReactiveCocoa/EXTKeyPathCoding.h>
+#import <objc/runtime.h>
+
+static void * UIControlRACCommandKey = &UIControlRACCommandKey;
+static void * UIControlRACCommandSignalKey = &UIControlRACCommandSignalKey;
+
+@implementation UIBarButtonItem (RACCommandSupport)
+
+- (RACCommand *)rac_command {
+ return objc_getAssociatedObject(self, UIControlRACCommandKey);
+}
+
+- (void)setRac_command:(RACCommand *)command {
+ objc_setAssociatedObject(self, UIControlRACCommandKey, command, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+
+ if (command == nil) return;
+
+ // Check for stored signal in order to remove it and add a new one
+ RACDisposable *existingSignal = objc_getAssociatedObject(self, UIControlRACCommandSignalKey);
+ [existingSignal dispose];
+
+ RACDisposable *newSignal = [RACAbleWithStart(command, canExecute) toProperty:@keypath(self.enabled) onObject:self];
+ objc_setAssociatedObject(self, UIControlRACCommandSignalKey, newSignal, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+
+ [self rac_hijackActionAndTargetIfNeeded];
+}
+
+- (void)rac_hijackActionAndTargetIfNeeded {
+ SEL hijackSelector = @selector(rac_commandPerformAction:);
+ if (self.target == self && self.action == hijackSelector) return;
+
+ if (self.target != nil) NSLog(@"WARNING: UIBarButtonItem.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

0 comments on commit daa9f2a

Please sign in to comment.
Something went wrong with that request. Please try again.