因为业务中经常要用到button的事件点击,但是习惯了BlockKit和RAC的高聚合事件点击写法以后,感觉方法要跳来跳去太麻烦了,特意写一个分类来修改这个弊端,这个分类还包括了一下功能:
1. addTarget点击事件
2. 按钮倒计时
3. 重新排布image和label的位置
主要代码如下:
.h
#import <UIKit/UIKit.h>
@interface UIButton (XHAdd)
//button中image和label的相对位置
typedef enum : NSUInteger{
XHButtonImageLocatedLabelTop,
XHButtonImageLocatedLabelButtom,
XHButtonImageLocatedLabelLeft,
XHButtonImageLocatedLabelRight
}XHButtonImageLocatedLabelEnum;
//设置使得图片和文字的位置改变
-(void)xh_ButtonImageLocatedLabel:(XHButtonImageLocatedLabelEnum)located whitSpace:(CGFloat)space;
//设置button在一定时间间隔内不能再次点击
-(void)xh_buttonBanWithTheCountdown:(int)time;
//设置某种点击事件后的回调
-(void)xh_blockWhitControlEvents:(UIControlEvents)ControlEvents block:(void(^)())block;
@end
.m
#import "UIButton+XHAdd.h"
#import "NSTimer+XHAdd.h"
#import <objc/runtime.h>
typedef void(^ButtonClikcBlock)();
@interface UIButton()
@property (nonatomic ,copy ) ButtonClikcBlock block;
@end
@implementation UIButton (HXAdd)
-(void)xh_ButtonImageLocatedLabel:(XHButtonImageLocatedLabelEnum)located whitSpace:(CGFloat)space{
// NSLog(@"label:%@,imageView:%@",self.titleLabel,self.imageView);
CGFloat imageWidth = self.imageView.frame.size.height;
CGFloat imageHeight = self.imageView.frame.size.width;
CGFloat labelWidth = 0.0;
CGFloat labelHeight = 0.0;
if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) {
// 由于iOS8中titleLabel的size为0,用下面的这种设置
labelWidth = self.titleLabel.intrinsicContentSize.width;
labelHeight = self.titleLabel.intrinsicContentSize.height;
}else{
labelWidth = self.titleLabel.frame.size.width;
labelHeight = self.titleLabel.frame.size.height;
}
// 2. 声明全局的imageEdgeInsets和labelEdgeInsets
UIEdgeInsets imageEdgeInsets = UIEdgeInsetsZero;
UIEdgeInsets labelEdgeInsets = UIEdgeInsetsZero;
// 3. 根据style和space得到imageEdgeInsets和labelEdgeInsets的值
switch (located) {
case XHButtonImageLocatedLabelTop:{
imageEdgeInsets = UIEdgeInsetsMake(-labelHeight-space/2.0, 0, 0, -labelWidth);
labelEdgeInsets = UIEdgeInsetsMake(0, -imageWidth, -imageHeight-space/2.0, 0);
}
break;
case XHButtonImageLocatedLabelButtom:{
imageEdgeInsets = UIEdgeInsetsMake(0, 0, -labelHeight-space/2.0, -labelWidth);
labelEdgeInsets = UIEdgeInsetsMake(-imageHeight-space/2.0, -imageWidth, 0, 0);
}
break;
case XHButtonImageLocatedLabelLeft:{
imageEdgeInsets = UIEdgeInsetsMake(0, -space/2.0, 0, space/2.0);
labelEdgeInsets = UIEdgeInsetsMake(0, space/2.0, 0, -space/2.0);
}
break;
case XHButtonImageLocatedLabelRight:{
imageEdgeInsets = UIEdgeInsetsMake(0, labelWidth+space/2.0, 0, -labelWidth-space/2.0);
labelEdgeInsets = UIEdgeInsetsMake(0, -imageWidth-space/2.0, 0, imageWidth+space/2.0);
}
break;
}
// 4. 赋值
self.titleEdgeInsets = labelEdgeInsets;
self.imageEdgeInsets = imageEdgeInsets;
}
-(void)xh_buttonBanWithTheCountdown:(int)time{
//1.禁止按钮多次点击
self.enabled = NO;
__block int count = time;
//2. 设置时间
[self setTitle:[NSString stringWithFormat:@"%ds",count] forState:UIControlStateDisabled];
//3. 开始倒计时(此处使用了NSTimer的分类来防止忘记取消定时器造成的其他影响)
__block NSTimer* timer = [NSTimer xh_scheduledTimerWithTimeInterval:1 block:^{
if (count <= 0) {
//5.销毁定时器
[timer invalidate];
timer = nil;
self.enabled = YES;
}else{
//4. 设置倒计时
count--;
[self setTitle:[NSString stringWithFormat:@"%ds",count] forState:UIControlStateDisabled];
}
} repeats:YES];
}
//addTarget事件
-(void)xh_blockWhitControlEvents:(UIControlEvents)ControlEvents block:(void(^)())block{
[self addTarget:self action:@selector(xh_buttonClick:) forControlEvents:ControlEvents];
self.block = block;
}
-(void)xh_buttonClick:(UIButton*)button{
if (self.block) {
self.block();
}
}
#pragma set/get
-(void)setBlock:(ButtonClikcBlock)block{
if (block) {
objc_setAssociatedObject(self, _cmd, block, OBJC_ASSOCIATION_COPY);
}
}
-(ButtonClikcBlock)block{
return objc_getAssociatedObject(self, @selector(setBlock:));
}
@end