通过分类实现对倒计时按钮的封装以及如何在分类添加属性

通过分类实现对倒计时按钮的封装以及如何在分类添加属性_第1张图片
按钮倒计时.gif
直接上代码
  #import 
      
  @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 

  @interface NSString (Category)

  //我要添加一个实例也可以访问的变量所以就写在这里了
  @property (nonatomic, strong) NSString *detailStr;

  @end
实现部分:
  #import "NSString+Category.h"
  #import 

  //用来标记是哪一个属性的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中缺少要是有的属性了,达到需求。

你可能感兴趣的:(通过分类实现对倒计时按钮的封装以及如何在分类添加属性)