SVPullToRefresh深入理解
[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); //访问属性 //第一个参数是原始对象,第二个参数是关联对象的key OBJC_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. */ };@dynamic属性声明
正常的属性都是用@synthesize来声明的(XCode4.0之后不需要了,编译时会自动生成get、set方法)。但是有时候我们的get、set方法要在运行时才动态绑定,这时就要用@dynamic。
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、四个状态,然后整体的动画都重新写。效果图如下(话说这个动画设计的实在是low):
loading.gif
动画分成两个阶段:
第一个阶段是还没进入加载阶段,这时候随着下拉的高度,中间的图片逐渐变大,扇形区域也逐渐变大。 第二个阶段是加载过程中,中间的图片开始旋转,同时像两侧发射出几个小图,旋转的同时透明度也发生变化,并来回震荡,直到加载结束。代码是基于SVPullToRefresh修改的,把用不着的代码全删了。项目已上传:Github。
startActivityForResult和setResult详解 原文:startActivityForResult和setResult详解 startActivityForResult与startActivity的不同之处在于:1、startActivity( ) 仅仅是跳转到目标页面,若是想跳回当前页面,则必须再使用一次startActivity( )。
之所以做这件事,是因为前者已经没有在维护了,所以把现在的下拉刷新框架PullToRefresh框架换成Android-Ultra-Pull-To-Refresh框架。
相关文章
- 第十四章·Kibana深入-Timelion画图实现系统监控
- Linux下定时任务配置深入理解
- 《深入理解Java虚拟机》读书笔记(六)
- Java学习笔记之二十六深入理解Java匿名内部类详解编程语言
- 深入理解Linux下VSFTP的配置(linux配置vsftp)
- 深入体验:yum 升级 MySQL(yum升级mysql)
- 深入了解MySQL常用的排序算法(mysql的排序算法)
- 学习Oracle:深入理解游标(oracle游标教程)
- 深入理解 Oracle 表的构成(oracle表的描述)
- 深入探索Linux:系统结构解析(linux系统结构详解)
- 深入理解Linux内核结构图(linux的内核结构图)
- 深入探究Linux内核:不断拓展的技术世界(深入理解linux 内核)
- 深入理解Oracle内存模块分析(oracle内存模块)
- 功能 深入理解Oracle中关闭ASM功能(oracle 关闭asm)
- 深入理解查找Redis安装位置(查找redis 安装位置)
- 深入理解JavaScript系列(4)立即调用的函数表达式
- 深入解析函数指针与返回函数的指针