New file |
| | |
| | | // |
| | | // UIControl+YYAdd.m |
| | | // YYCategories <https://github.com/ibireme/YYCategories> |
| | | // |
| | | // Created by ibireme on 13/4/5. |
| | | // Copyright (c) 2015 ibireme. |
| | | // |
| | | // This source code is licensed under the MIT-style license found in the |
| | | // LICENSE file in the root directory of this source tree. |
| | | // |
| | | |
| | | #import "UIControl+YYAdd.h" |
| | | #import "YYCategoriesMacro.h" |
| | | #import <objc/runtime.h> |
| | | |
| | | YYSYNTH_DUMMY_CLASS(UIControl_YYAdd) |
| | | |
| | | |
| | | static const int block_key; |
| | | |
| | | @interface _YYUIControlBlockTarget : NSObject |
| | | |
| | | @property (nonatomic, copy) void (^block)(id sender); |
| | | @property (nonatomic, assign) UIControlEvents events; |
| | | |
| | | - (id)initWithBlock:(void (^)(id sender))block events:(UIControlEvents)events; |
| | | - (void)invoke:(id)sender; |
| | | |
| | | @end |
| | | |
| | | @implementation _YYUIControlBlockTarget |
| | | |
| | | - (id)initWithBlock:(void (^)(id sender))block events:(UIControlEvents)events { |
| | | self = [super init]; |
| | | if (self) { |
| | | _block = [block copy]; |
| | | _events = events; |
| | | } |
| | | return self; |
| | | } |
| | | |
| | | - (void)invoke:(id)sender { |
| | | if (_block) _block(sender); |
| | | } |
| | | |
| | | @end |
| | | |
| | | |
| | | |
| | | @implementation UIControl (YYAdd) |
| | | |
| | | - (void)removeAllTargets { |
| | | [[self allTargets] enumerateObjectsUsingBlock: ^(id object, BOOL *stop) { |
| | | [self removeTarget:object action:NULL forControlEvents:UIControlEventAllEvents]; |
| | | }]; |
| | | [[self _yy_allUIControlBlockTargets] removeAllObjects]; |
| | | } |
| | | |
| | | - (void)setTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents { |
| | | if (!target || !action || !controlEvents) return; |
| | | NSSet *targets = [self allTargets]; |
| | | for (id currentTarget in targets) { |
| | | NSArray *actions = [self actionsForTarget:currentTarget forControlEvent:controlEvents]; |
| | | for (NSString *currentAction in actions) { |
| | | [self removeTarget:currentTarget action:NSSelectorFromString(currentAction) |
| | | forControlEvents:controlEvents]; |
| | | } |
| | | } |
| | | [self addTarget:target action:action forControlEvents:controlEvents]; |
| | | } |
| | | |
| | | - (void)addBlockForControlEvents:(UIControlEvents)controlEvents |
| | | block:(void (^)(id sender))block { |
| | | if (!controlEvents) return; |
| | | _YYUIControlBlockTarget *target = [[_YYUIControlBlockTarget alloc] |
| | | initWithBlock:block events:controlEvents]; |
| | | [self addTarget:target action:@selector(invoke:) forControlEvents:controlEvents]; |
| | | NSMutableArray *targets = [self _yy_allUIControlBlockTargets]; |
| | | [targets addObject:target]; |
| | | } |
| | | |
| | | - (void)setBlockForControlEvents:(UIControlEvents)controlEvents |
| | | block:(void (^)(id sender))block { |
| | | [self removeAllBlocksForControlEvents:UIControlEventAllEvents]; |
| | | [self addBlockForControlEvents:controlEvents block:block]; |
| | | } |
| | | |
| | | - (void)removeAllBlocksForControlEvents:(UIControlEvents)controlEvents { |
| | | if (!controlEvents) return; |
| | | |
| | | NSMutableArray *targets = [self _yy_allUIControlBlockTargets]; |
| | | NSMutableArray *removes = [NSMutableArray array]; |
| | | for (_YYUIControlBlockTarget *target in targets) { |
| | | if (target.events & controlEvents) { |
| | | UIControlEvents newEvent = target.events & (~controlEvents); |
| | | if (newEvent) { |
| | | [self removeTarget:target action:@selector(invoke:) forControlEvents:target.events]; |
| | | target.events = newEvent; |
| | | [self addTarget:target action:@selector(invoke:) forControlEvents:target.events]; |
| | | } else { |
| | | [self removeTarget:target action:@selector(invoke:) forControlEvents:target.events]; |
| | | [removes addObject:target]; |
| | | } |
| | | } |
| | | } |
| | | [targets removeObjectsInArray:removes]; |
| | | } |
| | | |
| | | - (NSMutableArray *)_yy_allUIControlBlockTargets { |
| | | NSMutableArray *targets = objc_getAssociatedObject(self, &block_key); |
| | | if (!targets) { |
| | | targets = [NSMutableArray array]; |
| | | objc_setAssociatedObject(self, &block_key, targets, OBJC_ASSOCIATION_RETAIN_NONATOMIC); |
| | | } |
| | | return targets; |
| | | } |
| | | |
| | | @end |