• 下拉刷新对象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 = 0;
                    if (currentPostion <= 0) {
                        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, 0, 0, 0);
            } completion:^(BOOL finished) {
    
            }];
        }
    }
    
    - (void)endRefresh {
        
        if (_delegate) {
            [_delegate endRefresh:self];
        }
        
        [UIView animateWithDuration:0.3f animations:^{
            _scrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
        } 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 并实现协议方法即可,使用的话,如下所示

  • 相关阅读:
    Bessie Goes Moo
    小P的强力值
    Max Flow
    约瑟夫
    Moocryption
    杂务
    排行榜
    银行贷款
    轰炸
    Contaminated Milk
  • 原文地址:https://www.cnblogs.com/YouXianMing/p/4601148.html
Copyright © 2020-2023  润新知