UIBarButtonItem+RACCommandSupport.m 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. //
  2. // UIBarButtonItem+RACCommandSupport.m
  3. // ReactiveCocoa
  4. //
  5. // Created by Kyle LeNeau on 3/27/13.
  6. // Copyright (c) 2013 GitHub, Inc. All rights reserved.
  7. //
  8. #import "UIBarButtonItem+RACCommandSupport.h"
  9. #import "RACEXTKeyPathCoding.h"
  10. #import "NSObject+RACPropertySubscribing.h"
  11. #import "RACCommand.h"
  12. #import "RACDisposable.h"
  13. #import "RACSignal+Operations.h"
  14. #import <objc/runtime.h>
  15. static void *UIControlRACCommandKey = &UIControlRACCommandKey;
  16. static void *UIControlEnabledDisposableKey = &UIControlEnabledDisposableKey;
  17. @implementation UIBarButtonItem (RACCommandSupport)
  18. - (RACCommand *)rac_command {
  19. return objc_getAssociatedObject(self, UIControlRACCommandKey);
  20. }
  21. - (void)setRac_command:(RACCommand *)command {
  22. objc_setAssociatedObject(self, UIControlRACCommandKey, command, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  23. // Check for stored signal in order to remove it and add a new one
  24. RACDisposable *disposable = objc_getAssociatedObject(self, UIControlEnabledDisposableKey);
  25. [disposable dispose];
  26. if (command == nil) return;
  27. disposable = [command.enabled setKeyPath:@keypath(self.enabled) onObject:self];
  28. objc_setAssociatedObject(self, UIControlEnabledDisposableKey, disposable, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  29. [self rac_hijackActionAndTargetIfNeeded];
  30. }
  31. - (void)rac_hijackActionAndTargetIfNeeded {
  32. SEL hijackSelector = @selector(rac_commandPerformAction:);
  33. if (self.target == self && self.action == hijackSelector) return;
  34. if (self.target != nil) NSLog(@"WARNING: UIBarButtonItem.rac_command hijacks the control's existing target and action.");
  35. self.target = self;
  36. self.action = hijackSelector;
  37. }
  38. - (void)rac_commandPerformAction:(id)sender {
  39. [self.rac_command execute:sender];
  40. }
  41. @end