UIButton+RACCommandSupport.m 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. //
  2. // UIButton+RACCommandSupport.m
  3. // ReactiveObjC
  4. //
  5. // Created by Ash Furrow on 2013-06-06.
  6. // Copyright (c) 2013 GitHub, Inc. All rights reserved.
  7. //
  8. #import "UIButton+RACCommandSupport.h"
  9. #import <ReactiveObjC/RACEXTKeyPathCoding.h>
  10. #import "RACCommand.h"
  11. #import "RACDisposable.h"
  12. #import "RACSignal+Operations.h"
  13. #import <objc/runtime.h>
  14. static void *UIButtonRACCommandKey = &UIButtonRACCommandKey;
  15. static void *UIButtonEnabledDisposableKey = &UIButtonEnabledDisposableKey;
  16. @implementation UIButton (RACCommandSupport)
  17. - (RACCommand *)rac_command {
  18. return objc_getAssociatedObject(self, UIButtonRACCommandKey);
  19. }
  20. - (void)setRac_command:(RACCommand *)command {
  21. objc_setAssociatedObject(self, UIButtonRACCommandKey, command, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  22. // Check for stored signal in order to remove it and add a new one
  23. RACDisposable *disposable = objc_getAssociatedObject(self, UIButtonEnabledDisposableKey);
  24. [disposable dispose];
  25. if (command == nil) return;
  26. disposable = [command.enabled setKeyPath:@keypath(self.enabled) onObject:self];
  27. objc_setAssociatedObject(self, UIButtonEnabledDisposableKey, disposable, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  28. [self rac_hijackActionAndTargetIfNeeded];
  29. }
  30. - (void)rac_hijackActionAndTargetIfNeeded {
  31. SEL hijackSelector = @selector(rac_commandPerformAction:);
  32. for (NSString *selector in [self actionsForTarget:self forControlEvent:UIControlEventTouchUpInside]) {
  33. if (hijackSelector == NSSelectorFromString(selector)) {
  34. return;
  35. }
  36. }
  37. [self addTarget:self action:hijackSelector forControlEvents:UIControlEventTouchUpInside];
  38. }
  39. - (void)rac_commandPerformAction:(id)sender {
  40. [self.rac_command execute:sender];
  41. }
  42. @end