UIControl+BlocksKit.m 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. //
  2. // UIControl+BlocksKit.m
  3. // BlocksKit
  4. //
  5. #import <objc/runtime.h>
  6. #import "UIControl+BlocksKit.h"
  7. static const void *BKControlHandlersKey = &BKControlHandlersKey;
  8. #pragma mark Private
  9. @interface BKControlWrapper : NSObject <NSCopying>
  10. - (id)initWithHandler:(void (^)(id sender))handler forControlEvents:(UIControlEvents)controlEvents;
  11. @property (nonatomic) UIControlEvents controlEvents;
  12. @property (nonatomic, copy) void (^handler)(id sender);
  13. @end
  14. @implementation BKControlWrapper
  15. - (id)initWithHandler:(void (^)(id sender))handler forControlEvents:(UIControlEvents)controlEvents
  16. {
  17. self = [super init];
  18. if (!self) return nil;
  19. self.handler = handler;
  20. self.controlEvents = controlEvents;
  21. return self;
  22. }
  23. - (id)copyWithZone:(NSZone *)zone
  24. {
  25. return [[BKControlWrapper alloc] initWithHandler:self.handler forControlEvents:self.controlEvents];
  26. }
  27. - (void)invoke:(id)sender
  28. {
  29. self.handler(sender);
  30. }
  31. @end
  32. #pragma mark Category
  33. @implementation UIControl (BlocksKit)
  34. - (void)bk_addEventHandler:(void (^)(id sender))handler forControlEvents:(UIControlEvents)controlEvents
  35. {
  36. NSParameterAssert(handler);
  37. NSMutableDictionary *events = objc_getAssociatedObject(self, BKControlHandlersKey);
  38. if (!events) {
  39. events = [NSMutableDictionary dictionary];
  40. objc_setAssociatedObject(self, BKControlHandlersKey, events, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  41. }
  42. NSNumber *key = @(controlEvents);
  43. NSMutableSet *handlers = events[key];
  44. if (!handlers) {
  45. handlers = [NSMutableSet set];
  46. events[key] = handlers;
  47. }
  48. BKControlWrapper *target = [[BKControlWrapper alloc] initWithHandler:handler forControlEvents:controlEvents];
  49. [handlers addObject:target];
  50. [self addTarget:target action:@selector(invoke:) forControlEvents:controlEvents];
  51. }
  52. - (void)bk_removeEventHandlersForControlEvents:(UIControlEvents)controlEvents
  53. {
  54. NSMutableDictionary *events = objc_getAssociatedObject(self, BKControlHandlersKey);
  55. if (!events) {
  56. events = [NSMutableDictionary dictionary];
  57. objc_setAssociatedObject(self, BKControlHandlersKey, events, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  58. }
  59. NSNumber *key = @(controlEvents);
  60. NSSet *handlers = events[key];
  61. if (!handlers)
  62. return;
  63. [handlers enumerateObjectsUsingBlock:^(id sender, BOOL *stop) {
  64. [self removeTarget:sender action:NULL forControlEvents:controlEvents];
  65. }];
  66. [events removeObjectForKey:key];
  67. }
  68. - (BOOL)bk_hasEventHandlersForControlEvents:(UIControlEvents)controlEvents
  69. {
  70. NSMutableDictionary *events = objc_getAssociatedObject(self, BKControlHandlersKey);
  71. if (!events) {
  72. events = [NSMutableDictionary dictionary];
  73. objc_setAssociatedObject(self, BKControlHandlersKey, events, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  74. }
  75. NSNumber *key = @(controlEvents);
  76. NSSet *handlers = events[key];
  77. if (!handlers)
  78. return NO;
  79. return !!handlers.count;
  80. }
  81. @end