利用runtime动态增加属性来封装一个全局调用loading效果
2016-05-11 16:00
357 查看
在ios开发中,category和associative是objective-c的扩展机制的两个特性,category是类型,可以通过它来扩展方法,;不过可以利用associative,通过它来扩展属性。
在平常项目中,这个我们经常用,比如对NSString扩展方法。相对的associative,就用的比较少,要用它必须使用
另外还有一个方法:
回到正题,我们app的loading需要在很多页面调用,如果每个页面都写创建方法,代码量就太大。放父类中呢,有的页面不需要loading,也不是很好。要是在UIView中加个扩展属性,那就随处可以调用了,并且只在当前UIView中显示loading。
首先,先封装个loading旋转动画,这里就不多阐述了,动画怎么实现的,可以直接看我文章最后github地址。这里主要讲扩展属性
然后新建一个UIView扩展UIView+Extension.h
这里面loadingView是扩展属性,在.m文件中,我们对他set get方法:
这样,我们就可以在扩展方法中调用开始加载方法
和停止加载方法
附上github地址
https://github.com/chenwei910101/YSLoadingDemo
在平常项目中,这个我们经常用,比如对NSString扩展方法。相对的associative,就用的比较少,要用它必须使用
<objc/runtime.h>的头文件,然后使用
objc_getAssociatedObject以及
objc_setAssociatedObject,我们来看下这两个方法:
OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);
OBJC_EXPORT id objc_getAssociatedObject(id object, const void *key) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);
另外还有一个方法:
OBJC_EXPORT void objc_removeAssociatedObjects(id object) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);
objc_getAssociatedObject、
objc_setAssociatedObject、
objc_removeAssociatedObjects都是Obj-c中的外联方法,object 参数作为待扩展的对象实例,key作为该对象实例的属性的键,而value就是对象实例的属性的值,policy作为关联的策略,它的枚举包括:
typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) { OBJC_ASSOCIATION_ASSIGN = 0, /**< Specifies a weak reference to the associated object. */ OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, /**< Specifies a strong reference to the associated object. * The association is not made atomically. */ OBJC_ASSOCIATION_COPY_NONATOMIC = 3, /**< Specifies that the associated object is copied. * The association is not made atomically. */ OBJC_ASSOCIATION_RETAIN = 01401, /**< Specifies a strong reference to the associated object. * The association is made atomically. */ OBJC_ASSOCIATION_COPY = 01403 /**< Specifies that the associated object is copied. * The association is made atomically. */ };
回到正题,我们app的loading需要在很多页面调用,如果每个页面都写创建方法,代码量就太大。放父类中呢,有的页面不需要loading,也不是很好。要是在UIView中加个扩展属性,那就随处可以调用了,并且只在当前UIView中显示loading。
首先,先封装个loading旋转动画,这里就不多阐述了,动画怎么实现的,可以直接看我文章最后github地址。这里主要讲扩展属性
#import "YSLoopView.h"
然后新建一个UIView扩展UIView+Extension.h
@interface UIView (Extension) @property (strong, nonatomic) YSLoadingView *loadingView; - (void)beginLoading; - (void)endLoading; @end
这里面loadingView是扩展属性,在.m文件中,我们对他set get方法:
@implementation UIView (Extension) static char LoadingViewKey; - (void)setLoadingView:(YSLoadingView *)loadingView{ [self willChangeValueForKey:@"LoadingViewKey"]; objc_setAssociatedObject(self, &LoadingViewKey, loadingView, OBJC_ASSOCIATION_RETAIN_NONATOMIC); [self didChangeValueForKey:@"LoadingViewKey"]; } - (YSLoadingView*)loadingView{ return objc_getAssociatedObject(self, &LoadingViewKey); }
这样,我们就可以在扩展方法中调用开始加载方法
- (void)beginLoading{ if (!self.loadingView) { self.loadingView = [[YSLoadingView alloc] initWithFrame:self.bounds]; [self.loadingView.titleLabel setText:@"加载中..."]; } [self addSubview:self.loadingView]; [self.loadingView startAnimating]; }
和停止加载方法
- (void)endLoading{ if (self.loadingView) { [self.loadingView stopAnimating]; } }
附上github地址
https://github.com/chenwei910101/YSLoadingDemo
相关文章推荐
- php7 扩展类的写法[2]
- php7 类的方法传参[3]
- php7 读取php.ini[4]
- C#、ASP.NET通用扩展工具类之TypeParse
- Lua编程示例(二):面向对象、metatable对表进行扩展
- Windows Powershell扩展类型系统
- Java Runtime Environment 5.0 Update 12 下载
- C#、ASP.NET通用扩展工具类之LogicSugar
- SQL Server下几个危险的扩展存储过程
- jQuery 学习第七课 扩展jQuery的功能 插件开发
- 运行Node.js的IIS扩展iisnode安装配置笔记
- 基于MySql的扩展功能生成全局ID
- jquery通过扩展select控件实现支持enter或focus选择的方法
- 一个扩展时间段的dir命令的vbs脚本
- Ruby中使用SWIG编写ruby扩展模块实例
- PHP memcache扩展的三种安装方法
- 用C/C++扩展你的PHP 为你的php增加功能
- .NET 扩展实现代码
- JS扩展方法实例分析
- JavaScript Array扩展实现代码