下拉刷新对象RefreshObject
下拉刷新对象RefreshObject

效果

说明
1. 分离了动画实现与刷新逻辑
2. 你可以根据自己的需要,设计自己的动画效果,你的动画只需要继承协议,实现协议里面的方法即可
3. 本设计方案是用的组件方式,代码复用率很高,灵活性很强
源码
https://github.com/YouXianMing/RefreshObject
//
// RefreshObjectAnimationProtocal.h
// TableViewRefresh
//
// Created by YouXianMing on 15/6/25.
// Copyright (c) 2015年 YouXianMing. All rights reserved.
// #import <Foundation/Foundation.h> @protocol RefreshObjectAnimationProtocal <NSObject> @required
- (void)animationWithPercent:(CGFloat)percent;
- (void)startRefreshAnimation;
- (void)endRefreshAnimation; @end
//
// RefreshObject.h
// UIScrollView
//
// Created by YouXianMing on 15/6/24.
// Copyright (c) 2015年 YouXianMing. All rights reserved.
// #import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@class RefreshObject; typedef enum : NSUInteger { NORMAL_STATE, // 正常状态
REFRESH_STATE, // 刷新状态 } ERefreshState; @protocol RefreshObjectDelegate <NSObject> @required
/**
* 开始刷新
*
* @param refreshObject
*/
- (void)startRefreshing:(RefreshObject *)refreshObject; /**
* 结束刷新
*
* @param refreshObject
*/
- (void)endRefresh:(RefreshObject *)refreshObject; - (void)moving:(RefreshObject *)refreshObject offset:(CGFloat)offset percent:(CGFloat)percent; @end @interface RefreshObject : NSObject /**
* 代理
*/
@property (nonatomic, weak) id <RefreshObjectDelegate> delegate; /**
* 当前状态
*/
@property (nonatomic, readonly) ERefreshState state;
@property (nonatomic) CGFloat height;
@property (nonatomic, weak) UIScrollView *scrollView; /**
* === 子类可以重写该方法实现新的刷新效果 ===
*
* 开始刷新
*/
- (void)beginRefreshing; /**
* === 子类可以重写该方法实现新的刷新效果 ===
*
* 结束刷新
*/
- (void)endRefresh; @end
//
// RefreshObject.m
// UIScrollView
//
// Created by YouXianMing on 15/6/24.
// Copyright (c) 2015年 YouXianMing. All rights reserved.
// #import "RefreshObject.h" @interface RefreshObject () @end @implementation RefreshObject - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { // 当前位置
float currentPostion = _scrollView.contentOffset.y; if (_scrollView.isDragging) {
// 拖拽中 if (_state == NORMAL_STATE) { // 获取位移的信息
if (_delegate) { CGFloat percent = ;
if (currentPostion <= ) {
percent = -currentPostion / _height;
} [_delegate moving:self offset:currentPostion percent:percent];
}
} } else {
// 停止拖拽 if (currentPostion < -_height) { [self beginRefreshing];
}
} } - (void)beginRefreshing { if (_state == NORMAL_STATE) {
_state = REFRESH_STATE; if (_delegate) {
[_delegate startRefreshing:self];
} [UIView animateWithDuration:0.3 animations:^{
_scrollView.contentInset = UIEdgeInsetsMake(_height, , , );
} completion:^(BOOL finished) { }];
}
} - (void)endRefresh { if (_delegate) {
[_delegate endRefresh:self];
} [UIView animateWithDuration:0.3f animations:^{
_scrollView.contentInset = UIEdgeInsetsMake(, , , );
} completion:^(BOOL finished) {
_state = NORMAL_STATE;
}];
} @end
//
// UIScrollView+RefreshObject.h
// UIScrollView
//
// Created by YouXianMing on 15/6/24.
// Copyright (c) 2015年 YouXianMing. All rights reserved.
// #import <UIKit/UIKit.h>
#import "RefreshObject.h" @interface UIScrollView (RefreshObject) /**
* 需要主动赋值
*/
@property (nonatomic, strong) RefreshObject *refreshObject; /**
* 添加观察者
*/
- (void)addObserver; /**
* 移除观察者
*/
- (void)removeObserver; @end
//
// UIScrollView+RefreshObject.m
// UIScrollView
//
// Created by YouXianMing on 15/6/24.
// Copyright (c) 2015年 YouXianMing. All rights reserved.
// #import "UIScrollView+RefreshObject.h"
#import <objc/runtime.h> @implementation UIScrollView (RefreshObject) #pragma mark - 添加属性 @dynamic refreshObject; NSString * const _recognizerRefreshObject = @"recognizerRefreshObject"; - (void)setRefreshObject:(RefreshObject *)refreshObject { objc_setAssociatedObject(self, (__bridge const void *)(_recognizerRefreshObject), refreshObject, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
} - (RefreshObject *)refreshObject { return objc_getAssociatedObject(self, (__bridge const void *)(_recognizerRefreshObject));
} #pragma mark - - (void)addObserver { if (self.refreshObject && self.refreshObject.scrollView == nil) { // 获取scrollView
self.refreshObject.scrollView = self; // 添加监听
[self addObserver:self.refreshObject
forKeyPath:@"contentOffset"
options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
context:nil];
}
} - (void)removeObserver { if (self.refreshObject) { // 移除监听
[self removeObserver:self.refreshObject
forKeyPath:@"contentOffset"]; self.refreshObject.scrollView = nil;
self.refreshObject = nil;
}
} @end
细节

继承协议 RefreshObjectAnimationProtocal 并实现协议方法即可,使用的话,如下所示

下拉刷新对象RefreshObject的更多相关文章
- C#构造方法(函数) C#方法重载 C#字段和属性 MUI实现上拉加载和下拉刷新 SVN常用功能介绍(二) SVN常用功能介绍(一) ASP.NET常用内置对象之——Server sql server——子查询 C#接口 字符串的本质 AJAX原生JavaScript写法
C#构造方法(函数) 一.概括 1.通常创建一个对象的方法如图: 通过 Student tom = new Student(); 创建tom对象,这种创建实例的形式被称为构造方法. 简述:用来初 ...
- IOS第四天-新浪微博 -存储优化OAuth授权账号信息,下拉刷新,字典转模型
*************application - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOpti ...
- react + iscroll5 实现完美 下拉刷新,上拉加载
经过几天的反复折腾,总算做出一个体验还不错的列表页了,主要支持了下拉刷新,上拉加载两个功能. 一开始直接采用了react-iscroll插件,它是基于iscroll插件开发的组件.但是开发过程中,发现 ...
- Windows phone应用开发[22]-再谈下拉刷新
几周之前在博客更新一篇Windows phone应用开发[18]-下拉刷新 博文,有很多人在微博和博客评论中提到了很多问题.其实在实际项目中我基于这篇博文提出解决问题思路优化了这个解决方案.为了能够详 ...
- Windows phone应用开发[18]-下拉刷新
在windows phone 中采用数据列表时为了保证用户体验常遇到加载数据的问题.这个问题普遍到只要你用到数据列表就要早晚面对这个问题. 很多人会说这个问题已经有解决方案. 其实真正问题并不在于如何 ...
- 【转载】 Android PullToRefresh (ListView GridView 下拉刷新) 使用详解
Android下拉刷新pullToRefreshListViewGridView 转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/3 ...
- Android开发学习之路-下拉刷新以及GridView的使用
GridView是类似于ListView的控件,只是GridView可以使用多个列来呈现内容,而ListView是以行为单位,所以用法上是差不多的. 主布局文件,因为要做下拉刷新,所以加了一个Prog ...
- [Android]下拉刷新控件RefreshableView的实现
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4172483.html 需求:自定义一个ViewGroup,实现 ...
- Android PullToRefresh (GridView 下拉刷新上拉加载)
做这个需要自己去git hub上下载个pull-to-refresh 里面有个library为依赖包自己导到自己的项目中 (下载地址:https://github.com/chrisbanes/And ...
随机推荐
- Impala 使用的端口
下表中列出了 Impala 是用的 TCP 端口.在部署 Impala 之前,请确保每个系统上这些端口都是打开的. 组件 服务 端口 访问需求 备注 Impala Daemon Impala 守护进程 ...
- 8-lvs-负载均衡
注意: linux集群的时间需要一致 并发量在千万以上, 一般才会使用此种方式, 基于第四层进行ip欺骗, 使得nginx只接受上行流量, 下行流量通过具体执行的服务器直接返回 由章文嵩博士(淘宝) ...
- Java处理正则表达式特殊字符转义 转
正则需要转义字符:'$', '(', ')', '*', '+', '.', '[', ']', '?', '\\', '^', '{', '}', '|' 异常现象: java.util.reg ...
- SpringBoot入门 (四) 数据库访问之JdbcTemplate
本文记录在SpringBoot中使用JdbcTemplate访问数据库. 一 JDBC回顾 最早是在上学时接触的使用JDBC访问数据库,主要有以下几个步骤: 1 加载驱动 Class.forName( ...
- SC Create 创建一个Windows系统服务 转
转自:http://www.360doc.com/content/13/0428/09/7555793_281451268.shtml sc create Serv-U binpath= &q ...
- SQL Server操作结果集-并集 差集 交集 结果集排序
操作结果集 为了配合测试,特地建了两个表,并且添加了一些测试数据,其中重复记录为东吴的人物. 表:Person_1魏国人物 表:Person_2蜀国人物 A.Union形成并集 Union可以对两个或 ...
- Eclipse下安装SVN插件以及连接SVN服务并发布项目
Eclipse安装SVN插件 Help->Eclipse MarketPlace 查找并安装Subclipse插件 按默认步骤完成SVNEclipse插件的安装(安装完成后需要重启Eclipse ...
- 532 -数组中的K-diff对
例1: 输入: [3,1,4,1,5],k = 2 输出: 2 说明:阵列中有两个2-diff对,(1,3)和(3,5). 虽然我们在输入中有两个1,但我们应该只返回唯一对的数量. 例2: 输入: ...
- xshell复制粘贴
用户看到这个标题肯定会觉得小编脑子坏掉了,复制粘贴不就是Ctrl+C,Ctrl+V嘛,但是在xshell却不尽然. 现象: 在xshell界面中需要用到之前的一段代码,自然是选中,熟练的键入Ctrl+ ...
- JavaScript document和window属性及方法详解
[document对象] 该对象是window和frames对象的一个属性,是显示于窗口或框架内的一个文档. 属性 alinkColor 活动链接的颜色(ALINK) anchor 一个HTMI锚点 ...