谈谈SVPullToRefresh
来源:互联网 发布:成立淘宝客团队 编辑:程序博客网 时间:2024/06/06 00:39
网上看到别人分享的SVPullToRefresh 觉得不错 推荐给大家
原文链接:http://www.jianshu.com/p/783ac913120d
SVPullToRefresh是iOS上实现下拉刷新和上提加载的一个组件。使用场景仅限UIScrollView,只需要一行代码,就能添加下拉刷新的功能。
[tableView addPullToRefreshWithActionHandler:^{ // 预加载数据到dataSource, 向tableview插入cell // 完成时调用[tableView.pullToRefreshView stopAnimating] }];
准备研究之前google了一把SVPullToRefresh,发现除了github的官方地址,排在最前面的居然是我去年写的一篇博客。重新看了一遍,发现自己当时讲的很浅,很多关键的东西都是一笔带过,没有讲清楚。所以今天重写一篇,深入地介绍一下这个优秀的组件。
铺垫
Associative(关联)
一个现成的类,你无法修改,但是要增加方法,可以用Category;如果要添加属性,Category就无能为力了,只能使用Associative。Associative和Category同属于Runtime的运用,只是Category属于语法级别的封装,使用起来非常方便;而要使用Associative则必须手动调用一些相关方法,这些方法都可以在<objc/runtime.h>中找到。
Associative一共包含三个方法:
//设置属性//第一个参数是原始对象,第二个参数是关联对象的key,第三个参数是关联对象本身,第四个参数是关联的策略。//如果第三个参数是nil,则清空当前关联。OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);//访问属性//第一个参数是原始对象,第二个参数是关联对象的keyOBJC_EXPORT id objc_getAssociatedObject(id object, const void *key) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);//移除所有属性//参数是原始对象//这个方法会把对象重置回初始状态,因为无法保证别的地方是否也为该对象设置为关联对象。//所以在尽量使用objc_setAssociatedObject,并把第三个参数设成nil来替代。OBJC_EXPORT void objc_removeAssociatedObjects(id object) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_1);
关联策略(objc_AssociationPolicy)一共有5种类型,参照Property的定义,应该不难理解它们之间的区别。
enum { 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. */};
Associative其实是利用get/set方法模拟了一个属性,但它不是属性;正常的属性对应一个实例变量,在对象实例内部,而关联的属性其实实在其他地方占据了一块内存,当前实例能够通过get/set方法访问和修改它。
更多参考
@dynamic属性声明
正常的属性都是用@synthesize来声明的(XCode4.0之后不需要了,编译时会自动生成get、set方法)。但是有时候我们并不希望系统自动生成的get、set方法,要在运行时才动态绑定,这时就要用@dynamic。
KVO
KVO是用来检测对象的某个属性是否发生变化的机制。
//加入观察者- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;//移除观察者- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;
PullToRefresh实现机制
PullToRefresh就是在UIScrollView上面add了一个subview:PullToRefreshView。这个PullToRefreshView就是一个普通的View,宽度和UIScrollView相同,高度可以自定义,默认是60。
PullToRefreshView有四种状态:
typedef NS_ENUM(NSUInteger, SVPullToRefreshState) { SVPullToRefreshStateStopped = 0, SVPullToRefreshStateTriggered, SVPullToRefreshStateLoading, SVPullToRefreshStateAll = 10};
- SVPullToRefreshStateStopped:刷新停止状态,还没有触发刷新操作。
- SVPullToRefreshStateTriggered:刷新操作被触发,但还没有开始发送请求(只要用户手还没松开,不会发送请求)
- SVPullToRefreshStateLoading:已经发送请求,但数据还没回来,这时菊花一直在转。这时候UITableView的contentInset已经修改,使PullToRefreshView可见。
- SVPullToRefreshStateAll:初始化的时候用的。
如果不需要自定义,PullToRefreshView内置了一个默认版本,包含箭头、title、subtitle、time。
自定义也可以,在PullToRefreshView的viewForState数组中加入三中状态的视图,然后就可以显示自定义的UI了。
PullToRefreshView是UIScrollView的一个属性,这个属性是通过关联的方式绑定的。当用户滚动UIScrollView的时候,ContentOffset会发生变化,这时候UIScrollView的观察者PullToRefreshView就会收到通知,然后根据PullToRefreshView自身的状态和ContentOffset决定是否切换状态,并执行相应动画。
自定义
SVPullToRefresh自带的自定义功能比较鸡肋,就是根据不同的状态换不同的View。当你想做更多个性化的动画时,就比较捉急了。所以,我准备只保留其最核心的部分,比如关联、KVO、四个状态,然后整体的动画都重新写。效果图如下:
下拉刷新动画分成两个阶段:
- 第一个阶段是还没进入加载阶段,这时候随着下拉的高度,图片周围一圈扇形区域逐渐变大。
- 第二个阶段是加载过程中,中间的图片开始旋转,同时下面伸出一根点段不断伸缩,直到加载结束。
上滑动画是下拉动画的简化版,就是下拉动画的第二个阶段;
另外可以用一个属性来控制当没有更多数据的时候,显示没有更多数据。
因为无论是下拉动画、上滑动画或者是没有更多数据的显示,都是可自定义的。所以我把这些内容分别放在了3个类中,这3个类定义了几个public方法,如果要改动画的话只要改这几个类的方法实现即可,接口都不需要动(除非动画比较复杂)。这样做的好处是代码更清晰,便于修改。
代码是基于SVPullToRefresh修改的,默认的代码两个Category里面有许多UI、动画之类的代码,我把这些用不着的全删了。项目已上传:Github。
- 谈谈SVPullToRefresh
- SVPullToRefresh问题解决
- [IOS]SVPullToRefresh的使用
- SVPullToRefresh深入理解
- SVPullToRefresh深入理解
- SVPullToRefresh的用法
- iOS中的下拉刷新SVPullToRefresh
- iOS中的下拉刷新SVPullToRefresh
- iOS中的下拉刷新SVPullToRefresh
- iOS中的下拉刷新SVPullToRefresh
- SVPullToRefresh 下拉刷新导航栏位置错误
- 谈谈
- 谈谈~~
- 谈谈
- 使用SVPullToRefresh 报错 需要注意 以及一些刷新方法
- 使用开源库 SVPullToRefresh 实现上拉加载下拉刷新
- 使用开源库 SVPullToRefresh 实现上拉加载下拉刷新
- SVPullToRefresh问题解决 同时进行上拉和下拉刷新
- poj1036 dp
- javascript中定时器,主要用来实现局部刷新技术,或者定时调用某方法
- 单例模式+synchronized的学习
- BZOJ 4012 HNOI 2015 开店(shop) 一道简单的点剖题
- 删除恶意资料
- 谈谈SVPullToRefresh
- hadoop命令详解
- POJ 1704 Georgia and Bob【博弈】
- CSS:box-sizing的使用
- SpriteKit与SceneKit
- Hbase shell详情
- 打印1到最大的n位数
- PHP字符串函数之 strstr stristr strchr strrchr
- Android_SlidingMenu开源项目_导航框架实现侧滑