直接上代码
#import <UIKit/UIKit.h>
@interface UIButton (countDown)
/**
* 倒计时按钮
*
* @param timeLine 倒计时总时间
* @param title 还没倒计时的title
* @param subTitle 倒计时中的子名字,如时、分
* @param mColor 还没倒计时的颜色
* @param color 倒计时中的颜色
*/
- (void)startWithTime:(NSInteger)timeLine title:(NSString *)title countDownTitle:(NSString *)subTitle mainColor:(UIColor *)mColor countColor:(UIColor *)color;
@end
实现部分:
#import "UIButton+countDown.h"
@implementation UIButton (countDown)
- (void)startWithTime:(NSInteger)timeLine title:(NSString *)title countDownTitle:(NSString *)subTitle mainColor:(UIColor *)mColor countColor:(UIColor *)color {
//倒计时时间
__block NSInteger timeOut = timeLine;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
//每秒执行一次
dispatch_source_set_timer(_timer, dispatch_walltime(NULL, 0), 1.0 * NSEC_PER_SEC, 0);
dispatch_source_set_event_handler(_timer, ^{
//倒计时结束,关闭
if (timeOut <= 0) {
dispatch_source_cancel(_timer);
dispatch_async(dispatch_get_main_queue(), ^{
self.backgroundColor = mColor;
[self setTitle:title forState:UIControlStateNormal];
self.userInteractionEnabled = YES;
});
} else {
int allTime = (int)timeLine + 1;
int seconds = timeOut % allTime;
NSString *timeStr = [NSString stringWithFormat:@"%0.2d", seconds];
dispatch_async(dispatch_get_main_queue(), ^{
self.backgroundColor = color;
[self setTitle:[NSString stringWithFormat:@"%@%@",timeStr,subTitle] forState:UIControlStateNormal];
self.userInteractionEnabled = NO;
});
timeOut--;
}
});
dispatch_resume(_timer);
}
@end
什么是分类:
1.分类能够做到的事情主要是:即使在你不知道一个类的源码情况下,向这个类添加扩展的方法。同时分类能够保证你的实现类和其他的文件区分开。Category的方法不一定非要在@implementation中实现,也可以在其他位置实现,但是当调用Category的方法时,依据继承树没有找到该方法的实现,程序则会崩溃。
2.值得注意的是Category理论上不能添加属性
既然说是理论上不可以添加属性,就是可以做到添加属性。这里可以使用Runtime来实现
说明在代码中:
#import <Foundation/Foundation.h>
@interface NSString (Category)
//我要添加一个实例也可以访问的变量所以就写在这里了
@property (nonatomic, strong) NSString *detailStr;
@end
实现部分:
#import "NSString+Category.h"
#import <objc/runtime.h>
//用来标记是哪一个属性的key
static void *detailStrKey = &detailStrKey;
@implementation NSString (Category)
-(void)setDetailStr:(NSString *)detailStr
{
//这个方法有四个参数,分别是:源对象,关联时的用来标记是哪一个属性的key(因为你可能要添加很多属性),关联的对象和一个关联策略。
objc_setAssociatedObject(self, &detailStrKey, detailStr, OBJC_ASSOCIATION_COPY);
}
-(NSString *)detailStr
{
// 获取相关联的对象
return objc_getAssociatedObject(self, &detailStrKey);
}
@end
这样就能满足当我们需要使用Class中缺少要是有的属性了,达到需求。