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

按钮倒计时.gif
直接上代码
  #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中缺少要是有的属性了,达到需求。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 5,899评论 0 9
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 14,780评论 4 61
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,242评论 19 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 176,852评论 25 709
  • 作者:Kelvin Lau , 原文链接,原文日期:2016-07-11译者:Darin4lin Swift算法俱...
    Darin4lin阅读 2,563评论 0 0

友情链接更多精彩内容