UIControl+YYAdd.m 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. //
  2. // UIControl+YYAdd.m
  3. // YYKit <https://github.com/ibireme/YYKit>
  4. //
  5. // Created by ibireme on 13/4/5.
  6. // Copyright (c) 2015 ibireme.
  7. //
  8. // This source code is licensed under the MIT-style license found in the
  9. // LICENSE file in the root directory of this source tree.
  10. //
  11. #import "UIControl+YYAdd.h"
  12. #import <objc/runtime.h>
  13. static const int block_key;
  14. @interface _YYUIControlBlockTarget : NSObject
  15. @property (nonatomic, copy) void (^block)(id sender);
  16. @property (nonatomic, assign) UIControlEvents events;
  17. - (id)initWithBlock:(void (^)(id sender))block events:(UIControlEvents)events;
  18. - (void)invoke:(id)sender;
  19. @end
  20. @implementation _YYUIControlBlockTarget
  21. - (id)initWithBlock:(void (^)(id sender))block events:(UIControlEvents)events {
  22. self = [super init];
  23. if (self) {
  24. _block = [block copy];
  25. _events = events;
  26. }
  27. return self;
  28. }
  29. - (void)invoke:(id)sender {
  30. if (_block) _block(sender);
  31. }
  32. @end
  33. @implementation UIControl (YYAdd)
  34. - (void)removeAllTargets {
  35. [[self allTargets] enumerateObjectsUsingBlock: ^(id object, BOOL *stop) {
  36. [self removeTarget:object
  37. action:NULL
  38. forControlEvents:UIControlEventAllEvents];
  39. }];
  40. }
  41. - (void)setTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents {
  42. NSSet *targets = [self allTargets];
  43. for (id currentTarget in targets) {
  44. NSArray *actions = [self actionsForTarget:currentTarget forControlEvent:controlEvents];
  45. for (NSString *currentAction in actions) {
  46. [self removeTarget:currentTarget action:NSSelectorFromString(currentAction)
  47. forControlEvents:controlEvents];
  48. }
  49. }
  50. [self addTarget:target action:action forControlEvents:controlEvents];
  51. }
  52. - (void)addBlockForControlEvents:(UIControlEvents)controlEvents
  53. block:(void (^)(id sender))block {
  54. _YYUIControlBlockTarget *target = [[_YYUIControlBlockTarget alloc]
  55. initWithBlock:block events:controlEvents];
  56. [self addTarget:target action:@selector(invoke:) forControlEvents:controlEvents];
  57. NSMutableArray *targets = [self _yy_allUIControlBlockTargets];
  58. [targets addObject:target];
  59. }
  60. - (void)setBlockForControlEvents:(UIControlEvents)controlEvents
  61. block:(void (^)(id sender))block {
  62. [self removeAllBlocksForControlEvents:controlEvents];
  63. [self addBlockForControlEvents:controlEvents block:block];
  64. }
  65. - (void)removeAllBlocksForControlEvents:(UIControlEvents)controlEvents {
  66. NSMutableArray *targets = [self _yy_allUIControlBlockTargets];
  67. NSMutableArray *removes = [NSMutableArray array];
  68. [targets enumerateObjectsUsingBlock: ^(id obj, NSUInteger idx, BOOL *stop) {
  69. _YYUIControlBlockTarget *target = (_YYUIControlBlockTarget *)obj;
  70. if (target.events == controlEvents) {
  71. [removes addObject:target];
  72. [self removeTarget:target
  73. action:@selector(invoke:)
  74. forControlEvents:controlEvents];
  75. }
  76. }];
  77. [targets removeObjectsInArray:removes];
  78. }
  79. - (NSMutableArray *)_yy_allUIControlBlockTargets {
  80. NSMutableArray *targets = objc_getAssociatedObject(self, &block_key);
  81. if (!targets) {
  82. targets = [NSMutableArray array];
  83. objc_setAssociatedObject(self, &block_key, targets, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  84. }
  85. return targets;
  86. }
  87. @end