下拉刷新对象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的更多相关文章

  1. C#构造方法(函数) C#方法重载 C#字段和属性 MUI实现上拉加载和下拉刷新 SVN常用功能介绍(二) SVN常用功能介绍(一) ASP.NET常用内置对象之——Server sql server——子查询 C#接口 字符串的本质 AJAX原生JavaScript写法

    C#构造方法(函数)   一.概括 1.通常创建一个对象的方法如图: 通过  Student tom = new Student(); 创建tom对象,这种创建实例的形式被称为构造方法. 简述:用来初 ...

  2. IOS第四天-新浪微博 -存储优化OAuth授权账号信息,下拉刷新,字典转模型

    *************application - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOpti ...

  3. react + iscroll5 实现完美 下拉刷新,上拉加载

    经过几天的反复折腾,总算做出一个体验还不错的列表页了,主要支持了下拉刷新,上拉加载两个功能. 一开始直接采用了react-iscroll插件,它是基于iscroll插件开发的组件.但是开发过程中,发现 ...

  4. Windows phone应用开发[22]-再谈下拉刷新

    几周之前在博客更新一篇Windows phone应用开发[18]-下拉刷新 博文,有很多人在微博和博客评论中提到了很多问题.其实在实际项目中我基于这篇博文提出解决问题思路优化了这个解决方案.为了能够详 ...

  5. Windows phone应用开发[18]-下拉刷新

    在windows phone 中采用数据列表时为了保证用户体验常遇到加载数据的问题.这个问题普遍到只要你用到数据列表就要早晚面对这个问题. 很多人会说这个问题已经有解决方案. 其实真正问题并不在于如何 ...

  6. 【转载】 Android PullToRefresh (ListView GridView 下拉刷新) 使用详解

    Android下拉刷新pullToRefreshListViewGridView 转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/3 ...

  7. Android开发学习之路-下拉刷新以及GridView的使用

    GridView是类似于ListView的控件,只是GridView可以使用多个列来呈现内容,而ListView是以行为单位,所以用法上是差不多的. 主布局文件,因为要做下拉刷新,所以加了一个Prog ...

  8. [Android]下拉刷新控件RefreshableView的实现

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4172483.html 需求:自定义一个ViewGroup,实现 ...

  9. Android PullToRefresh (GridView 下拉刷新上拉加载)

    做这个需要自己去git hub上下载个pull-to-refresh 里面有个library为依赖包自己导到自己的项目中 (下载地址:https://github.com/chrisbanes/And ...

随机推荐

  1. 全局描述符表(GDT)——《x86汇编语言:从实模式到保护模式》读书笔记09

    在进入保护模式之前,我们先要学习一些基础知识.今天我们看一下全局描述符表(Global Descriptor Table, 简称GDT). 同实模式一样,在保护模式下,对内存的访问仍然使用段地址加偏移 ...

  2. spring整合mongodb

    使用spring整合mongodb maven 依赖 <dependency> <groupId>org.mongodb</groupId> <artifac ...

  3. java.lang 类String

    方法摘要1  charcharAt(int index) 返回指定索引处的 char 值.               index - char 值的索引.2 string       concat( ...

  4. [有料组每日学习分享计划--00087]32行代码帮你导出IOS酷我音乐下载的无损音乐

    需求与研究: 1.IOS的酷我音乐软件,还是不错滴,可以直接下载APE或是320K的MP3音乐,但是我发现PC上的酷我反而没这个功能,而且其他的音乐软件一般只能下载中低品质的音乐.所以能够从IOS中找 ...

  5. 上传多张图片imgupload

    <tr> <td class="listtitle-up">尿素箱</td> <td> <div class="co ...

  6. 关于C#判断是否是数字的正则式

    有话要说 今天我同事突然让我帮他看个问题,他说想不通为什么数据库中会有不合法的内容,我都已经用正则过滤了,并且在本地调通了的! 我问他是不是你正则有问题,他说没问题啊,前端和后端的正则是一样的,前端我 ...

  7. 自己写一个java的mvc框架吧(一)

    自己写一个mvc框架吧(一) 目录 自己写一个mvc框架吧(一) 自己写一个mvc框架吧(二) 自己写一个mvc框架吧(三) 自己写一个mvc框架吧(四) 写之前的一些废话 废话 1 (总是要先随便说 ...

  8. 【转】HttpServletRequestWrapper 实现xss注入

    这里说下最近项目中我们的解决方案,主要用到commons-lang3-3.1.jar这个包的org.apache.commons.lang3.StringEscapeUtils.escapeHtml4 ...

  9. item2 快捷键

    快捷键 ⌘ + Click:可以打开文件,文件夹和链接 ⌘ + n:新建窗口 ⌘ + t:新建标签页 ⌘ + w:关闭当前页 ⌘ + 数字 & ⌘ + 方向键:切换标签页 ⌥⌘ + 数字:切换 ...

  10. 纯小白入手 vue3.0 CLI - 1 - npm 安装与初始化

    node 开发环境请先自行准备 npm install -g @vue/cli 安装完成之后命令行则存在 vue 命令 vue -V 查看本地 vue 版本 vue -h 输出帮助 vue creat ...