利用runtime动态增加属性来封装一个全局调用loading效果

在ios开发中,category和associative是objective-c的扩展机制的两个特性,category是类型,可以通过它来扩展方法,;不过可以利用associative,通过它来扩展属性。

在平常项目中,这个我们经常用,比如对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_getAssociatedObjectobjc_setAssociatedObjectobjc_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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值