下拉刷新对象RefreshObject

效果

说明

1. 分离了动画实现与刷新逻辑

2. 你可以根据自己的需要,设计自己的动画效果,你的动画只需要继承协议,实现协议里面的方法即可

3. 本设计方案是用的组件方式,代码复用率很高,灵活性很强

源码

https://github.com/YouXianMing/RefreshObject

  1. //
  2. // RefreshObjectAnimationProtocal.h
  3. // TableViewRefresh
  4. //
  5. // Created by YouXianMing on 15/6/25.
  6. // Copyright (c) 2015年 YouXianMing. All rights reserved.
  7. //
  8.  
  9. #import <Foundation/Foundation.h>
  10.  
  11. @protocol RefreshObjectAnimationProtocal <NSObject>
  12.  
  13. @required
  14. - (void)animationWithPercent:(CGFloat)percent;
  15. - (void)startRefreshAnimation;
  16. - (void)endRefreshAnimation;
  17.  
  18. @end
  1. //
  2. // RefreshObject.h
  3. // UIScrollView
  4. //
  5. // Created by YouXianMing on 15/6/24.
  6. // Copyright (c) 2015年 YouXianMing. All rights reserved.
  7. //
  8.  
  9. #import <Foundation/Foundation.h>
  10. #import <UIKit/UIKit.h>
  11. @class RefreshObject;
  12.  
  13. typedef enum : NSUInteger {
  14.  
  15. NORMAL_STATE, // 正常状态
  16. REFRESH_STATE, // 刷新状态
  17.  
  18. } ERefreshState;
  19.  
  20. @protocol RefreshObjectDelegate <NSObject>
  21.  
  22. @required
  23. /**
  24. * 开始刷新
  25. *
  26. * @param refreshObject
  27. */
  28. - (void)startRefreshing:(RefreshObject *)refreshObject;
  29.  
  30. /**
  31. * 结束刷新
  32. *
  33. * @param refreshObject
  34. */
  35. - (void)endRefresh:(RefreshObject *)refreshObject;
  36.  
  37. - (void)moving:(RefreshObject *)refreshObject offset:(CGFloat)offset percent:(CGFloat)percent;
  38.  
  39. @end
  40.  
  41. @interface RefreshObject : NSObject
  42.  
  43. /**
  44. * 代理
  45. */
  46. @property (nonatomic, weak) id <RefreshObjectDelegate> delegate;
  47.  
  48. /**
  49. * 当前状态
  50. */
  51. @property (nonatomic, readonly) ERefreshState state;
  52. @property (nonatomic) CGFloat height;
  53. @property (nonatomic, weak) UIScrollView *scrollView;
  54.  
  55. /**
  56. * === 子类可以重写该方法实现新的刷新效果 ===
  57. *
  58. * 开始刷新
  59. */
  60. - (void)beginRefreshing;
  61.  
  62. /**
  63. * === 子类可以重写该方法实现新的刷新效果 ===
  64. *
  65. * 结束刷新
  66. */
  67. - (void)endRefresh;
  68.  
  69. @end
  1. //
  2. // RefreshObject.m
  3. // UIScrollView
  4. //
  5. // Created by YouXianMing on 15/6/24.
  6. // Copyright (c) 2015年 YouXianMing. All rights reserved.
  7. //
  8.  
  9. #import "RefreshObject.h"
  10.  
  11. @interface RefreshObject ()
  12.  
  13. @end
  14.  
  15. @implementation RefreshObject
  16.  
  17. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
  18.  
  19. // 当前位置
  20. float currentPostion = _scrollView.contentOffset.y;
  21.  
  22. if (_scrollView.isDragging) {
  23. // 拖拽中
  24.  
  25. if (_state == NORMAL_STATE) {
  26.  
  27. // 获取位移的信息
  28. if (_delegate) {
  29.  
  30. CGFloat percent = ;
  31. if (currentPostion <= ) {
  32. percent = -currentPostion / _height;
  33. }
  34.  
  35. [_delegate moving:self offset:currentPostion percent:percent];
  36. }
  37. }
  38.  
  39. } else {
  40. // 停止拖拽
  41.  
  42. if (currentPostion < -_height) {
  43.  
  44. [self beginRefreshing];
  45. }
  46. }
  47.  
  48. }
  49.  
  50. - (void)beginRefreshing {
  51.  
  52. if (_state == NORMAL_STATE) {
  53. _state = REFRESH_STATE;
  54.  
  55. if (_delegate) {
  56. [_delegate startRefreshing:self];
  57. }
  58.  
  59. [UIView animateWithDuration:0.3 animations:^{
  60. _scrollView.contentInset = UIEdgeInsetsMake(_height, , , );
  61. } completion:^(BOOL finished) {
  62.  
  63. }];
  64. }
  65. }
  66.  
  67. - (void)endRefresh {
  68.  
  69. if (_delegate) {
  70. [_delegate endRefresh:self];
  71. }
  72.  
  73. [UIView animateWithDuration:0.3f animations:^{
  74. _scrollView.contentInset = UIEdgeInsetsMake(, , , );
  75. } completion:^(BOOL finished) {
  76. _state = NORMAL_STATE;
  77. }];
  78. }
  79.  
  80. @end
  1. //
  2. // UIScrollView+RefreshObject.h
  3. // UIScrollView
  4. //
  5. // Created by YouXianMing on 15/6/24.
  6. // Copyright (c) 2015年 YouXianMing. All rights reserved.
  7. //
  8.  
  9. #import <UIKit/UIKit.h>
  10. #import "RefreshObject.h"
  11.  
  12. @interface UIScrollView (RefreshObject)
  13.  
  14. /**
  15. * 需要主动赋值
  16. */
  17. @property (nonatomic, strong) RefreshObject *refreshObject;
  18.  
  19. /**
  20. * 添加观察者
  21. */
  22. - (void)addObserver;
  23.  
  24. /**
  25. * 移除观察者
  26. */
  27. - (void)removeObserver;
  28.  
  29. @end
  1. //
  2. // UIScrollView+RefreshObject.m
  3. // UIScrollView
  4. //
  5. // Created by YouXianMing on 15/6/24.
  6. // Copyright (c) 2015年 YouXianMing. All rights reserved.
  7. //
  8.  
  9. #import "UIScrollView+RefreshObject.h"
  10. #import <objc/runtime.h>
  11.  
  12. @implementation UIScrollView (RefreshObject)
  13.  
  14. #pragma mark - 添加属性
  15.  
  16. @dynamic refreshObject;
  17.  
  18. NSString * const _recognizerRefreshObject = @"recognizerRefreshObject";
  19.  
  20. - (void)setRefreshObject:(RefreshObject *)refreshObject {
  21.  
  22. objc_setAssociatedObject(self, (__bridge const void *)(_recognizerRefreshObject), refreshObject, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  23. }
  24.  
  25. - (RefreshObject *)refreshObject {
  26.  
  27. return objc_getAssociatedObject(self, (__bridge const void *)(_recognizerRefreshObject));
  28. }
  29.  
  30. #pragma mark -
  31.  
  32. - (void)addObserver {
  33.  
  34. if (self.refreshObject && self.refreshObject.scrollView == nil) {
  35.  
  36. // 获取scrollView
  37. self.refreshObject.scrollView = self;
  38.  
  39. // 添加监听
  40. [self addObserver:self.refreshObject
  41. forKeyPath:@"contentOffset"
  42. options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
  43. context:nil];
  44. }
  45. }
  46.  
  47. - (void)removeObserver {
  48.  
  49. if (self.refreshObject) {
  50.  
  51. // 移除监听
  52. [self removeObserver:self.refreshObject
  53. forKeyPath:@"contentOffset"];
  54.  
  55. self.refreshObject.scrollView = nil;
  56. self.refreshObject = nil;
  57. }
  58. }
  59.  
  60. @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. nginx 超时问题: upstream timed out (110: Connection timed out) while reading response header from upstream

    目录 错误内容 错误原因 错误解决办法 错误内容 我们可以在error.log 里面可以看到 错误内容:upstream timed out (110: Connection timed out) w ...

  2. spark job运行参数优化

    http://www.cnblogs.com/LBSer/p/4129481.html 一.问题 使用spark join两张表(5000w*500w)总是出错,报的异常显示是在shuffle阶段. ...

  3. 玩转mongodb(四):细说插入、更新、删除和查询

    插入: 使用insert或save方法想目标集合插入一个文档: db.person.insert({"name":"ryan","age": ...

  4. PTA (Advanced Level) 1021 Deepest Root

    Deepest Root A graph which is connected and acyclic can be considered a tree. The hight of the tree ...

  5. import.html 页面导出execl

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  6. double类型转换为int类型四舍五入工具类

    package com.qiyuan.util; import java.math.BigDecimal; import java.text.DecimalFormat; public class G ...

  7. oracle存储过程删除树状结构的表数据

    今天在删除一个车辆品牌表的时候,遇到了一个问题,是在java的代码中做逻辑删除还是直接在Oracle中一次删除完成呢 思来想去觉得还是在sql里直接删除比较合适, 为什么呢? 第一,涉及数据库的读写操 ...

  8. [转]微信小程序之购物车功能

    本文转自:https://www.cnblogs.com/linxin/p/6834206.html 前言 以往的购物车,基本都是通过大量的 DOM 操作来实现.微信小程序其实跟 vue.js 的用法 ...

  9. vb.net的String类型和Bytes转换(C#也适用)

    1.Bytes---->StringSystem.Text.Encoding.Unicode.GetString(bytes, 0, bytes.Length) 2.String----> ...

  10. EL表达式无法获取Spring MVC的Model封装好的数据解决方法

    1.在spring-mvc的配置文件中已经配置jsp的视图解析器 2.在Controller中使用Model的addAttribute方法添加属性name,msg 3.在jsp页面中使用${msg}取 ...