zoukankan      html  css  js  c++  java
  • 上拉加载下拉刷新控件WaterRefreshLoadMoreView

    上拉加载下拉刷新控件WaterRefreshLoadMoreView

    效果:

    源码:

    //
    //  SRSlimeView
    //  @author  SR
    //  Modified by JunHan on 13-9-18.
    //
    
    #import <UIKit/UIKit.h>
    
    #define kStartTo    0.7f
    #define kEndTo      0.15f
    #define kAnimationInterval  (1.0f / 50.0f)
    
    NS_INLINE CGFloat distansBetween(CGPoint p1 , CGPoint p2) {
        return sqrtf((p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y));
    }
    
    typedef enum {
        SRSlimeStateNormal,
        SRSlimeStateShortening,
        SRSlimeStateMiss
    } SRSlimeState;
    
    @class SRSlimeView;
    
    @interface SRSlimeView : UIView
    
    @property (nonatomic, assign)   CGPoint startPoint, toPoint;
    @property (nonatomic, assign)   CGFloat viscous;    //default 55
    @property (nonatomic, assign)   CGFloat radius;     //default 13
    @property (nonatomic, assign)   CGFloat lineWith;
    @property (nonatomic, assign)   CGFloat shadowBlur;
    
    @property (nonatomic, strong)   UIColor *bodyColor, *skinColor;
    @property (nonatomic, strong)   UIColor *shadowColor;
    
    @property (nonatomic, assign)   SRSlimeState state;
    
    - (void)setPullApartTarget:(id)target action:(SEL)action;
    
    @end
    SRSlimeView.h
    //
    //  SRSlimeView
    //  @author  SR
    //  Modified by JunHan on 13-9-18.
    //
    
    #import "SRSlimeView.h"
    #import <QuartzCore/QuartzCore.h>
    
    NS_INLINE CGPoint pointLineToArc(CGPoint center, CGPoint p2, float angle, CGFloat radius) {
        float angleS = atan2f(p2.y - center.y, p2.x - center.x);
        float angleT = angleS + angle;
        float x = radius * cosf(angleT);
        float y = radius * sinf(angleT);
        return CGPointMake(x + center.x, y + center.y);
    }
    
    @implementation SRSlimeView {
        __weak id  _target;
        SEL _action;
    }
    
    - (id)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            self.backgroundColor = [UIColor clearColor];
            _toPoint = _startPoint = CGPointMake(frame.size.width / 2,
                                                 frame.size.height / 2);
            _viscous = 45.0f; // 拉扯长度
            _radius = 17.0f;  // 拉扯物体半径
            _bodyColor = [[UIColor grayColor] colorWithAlphaComponent:0.45f];
            _skinColor = [[UIColor blackColor] colorWithAlphaComponent:0.12f];
            _lineWith = 1.0;
            _shadowBlur = 4;
            _shadowColor = [[UIColor grayColor] colorWithAlphaComponent:0.7f];
        }
        return self;
    }
    
    - (void)setLineWith:(CGFloat)lineWith
    {
        _lineWith = lineWith;
        [self setNeedsDisplay];
    }
    
    - (void)setStartPoint:(CGPoint)startPoint
    {
        if (CGPointEqualToPoint(_startPoint, startPoint))
            return;
        if (_state == SRSlimeStateNormal) {
            _startPoint = startPoint;
            [self setNeedsDisplay];
        }
    }
    
    - (void)setToPoint:(CGPoint)toPoint
    {
        if (CGPointEqualToPoint(_toPoint, toPoint))
            return;
        if (_state == SRSlimeStateNormal) {
            _toPoint = toPoint;
            [self setNeedsDisplay];
        }
    }
    
    - (UIBezierPath*)bodyPath:(CGFloat)startRadius end:(CGFloat)endRadius percent:(float)percent
    {
        UIBezierPath *path = [[UIBezierPath alloc] init];
        float angle1 = M_PI/3 + (M_PI/6) * percent;
        CGPoint sp1 = pointLineToArc(_startPoint, _toPoint, angle1, startRadius),
        sp2 = pointLineToArc(_startPoint, _toPoint, -angle1, startRadius),
        ep1 = pointLineToArc(_toPoint, _startPoint, M_PI/2, endRadius),
        ep2 = pointLineToArc(_toPoint, _startPoint, -M_PI/2, endRadius);
    #define kMiddleP  0.6
        CGPoint mp1 = CGPointMake(sp2.x*kMiddleP + ep1.x*(1-kMiddleP), sp2.y*kMiddleP + ep1.y*(1-kMiddleP)),
        mp2 = CGPointMake(sp1.x*kMiddleP + ep2.x*(1-kMiddleP), sp1.y*kMiddleP + ep2.y*(1-kMiddleP)),
        mm = CGPointMake((mp1.x + mp2.x)/2, (mp1.y + mp2.y)/2);
        float p = distansBetween(mp1, mp2) / 2 / endRadius * (0.9 + percent/10);
        mp1 = CGPointMake((mp1.x - mm.x)/p + mm.x, (mp1.y - mm.y)/p + mm.y);
        mp2 = CGPointMake((mp2.x - mm.x)/p + mm.x, (mp2.y - mm.y)/p + mm.y);
        [path moveToPoint:sp1];
        float angleS = atan2f(_toPoint.y - _startPoint.y,
                              _toPoint.x - _startPoint.x);
        [path addArcWithCenter:_startPoint
                        radius:startRadius
                    startAngle:angleS + angle1
                      endAngle:angleS + M_PI*2 - angle1
                     clockwise:YES];
        
        [path addQuadCurveToPoint:ep1
                     controlPoint:mp1];
        angleS = atan2f(_startPoint.y - _toPoint.y,
                        _startPoint.x - _toPoint.x);
        [path addArcWithCenter:_toPoint
                        radius:endRadius
                    startAngle:angleS + M_PI/2
                      endAngle:angleS + M_PI*3/2
                     clockwise:YES];
        [path addQuadCurveToPoint:sp1
                     controlPoint:mp2];
        
        return path;
    }
    
    - (void)drawRect:(CGRect)rect
    {
        switch (_state) {
            case SRSlimeStateNormal:
            {
                float percent = 1 - distansBetween(_startPoint , _toPoint) / _viscous;
                if (percent == 1) {
                    CGContextRef context = UIGraphicsGetCurrentContext();
                    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(_startPoint.x - _radius, _startPoint.y - _radius, 2*_radius, 2*_radius)
                                          
                                                                    cornerRadius:_radius];
                    [self setContext:context path:path];
                    CGContextDrawPath(context, kCGPathFillStroke);
                }else {
                    CGFloat startRadius = _radius * (kStartTo + (1 - kStartTo) * percent);
                    CGFloat endRadius = _radius * (kEndTo + (1 - kEndTo) * percent);
                    CGContextRef context = UIGraphicsGetCurrentContext();
                    // build curve path
                    UIBezierPath *path = [self bodyPath:startRadius
                                                    end:endRadius
                                                percent:percent];
                    [self setContext:context path:path];
                    CGContextDrawPath(context, kCGPathFillStroke);
                    if (percent <= 0) {
                        _state = SRSlimeStateShortening;
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
                        [_target performSelector:_action
                                      withObject:self];
    #pragma clang diagnostic pop
                        [self performSelector:@selector(scaling)
                                   withObject:nil
                                   afterDelay:kAnimationInterval
                                      inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]];
                    }
                }
            }
                break;
            case SRSlimeStateShortening:
            {
                // back shortneing
                _toPoint = CGPointMake((_toPoint.x - _startPoint.x) * 0.8 + _startPoint.x,
                                       (_toPoint.y - _startPoint.y) * 0.8 + _startPoint.y);
                float p = distansBetween(_startPoint, _toPoint) / _viscous;
                float percent = 1 - p;
                float r = _radius * p;
                
                if (p > 0.01) {
                    CGFloat startRadius = r * (kStartTo + (1 - kStartTo) * percent);
                    CGContextRef context = UIGraphicsGetCurrentContext();
                    
                    CGFloat endRadius = r * (kEndTo + (1 - kEndTo) * percent) * (1 + percent / 2);
                    UIBezierPath *path = [self bodyPath:startRadius
                                                    end:endRadius
                                                percent:percent];
                    [self setContext:context path:path];
                    CGContextDrawPath(context, kCGPathFillStroke);
                }else {
                    self.hidden = YES;
                    _state = SRSlimeStateMiss;
                }
            }
                break;
            default:
                break;
        }
    }
    
    - (void)setContext:(CGContextRef)context path:(UIBezierPath *)path {
        if (self.shadowColor) {
            CGContextSetShadowWithColor(context, CGSizeZero, self.shadowBlur, self.shadowColor.CGColor);
        }
        CGContextSetFillColorWithColor(context, self.bodyColor.CGColor); 
        CGContextSetLineWidth(context, self.lineWith);
        CGContextSetStrokeColorWithColor(context, self.skinColor.CGColor);
        CGContextAddPath(context, path.CGPath);
    }
    
    - (void)scaling
    {
        if (_state == SRSlimeStateShortening) {
            [self setNeedsDisplay];
            [self performSelector:@selector(scaling)
                       withObject:nil
                       afterDelay:kAnimationInterval
                          inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]];
        }
    }
    
    - (void)setPullApartTarget:(id)target action:(SEL)action
    {
        _target = target;
        _action = action;
    }
    
    - (void)setHidden:(BOOL)hidden
    {
        [super setHidden:hidden];
        if (!hidden) {
            self.layer.transform = CATransform3DIdentity;
            [self setNeedsDisplay];
        }
    }
    
    - (void)setState:(SRSlimeState)state
    {
        _state = state;
        [NSObject cancelPreviousPerformRequestsWithTarget:self
                                                 selector:@selector(scaling)
                                                   object:nil];
    }
    
    @end
    SRSlimeView.m
    /**
     *  WaterRefreshLoadMoreView.h
     *  A refresh view looks like UIRefreshControl and have loadMore function
     *  (水滴下拉刷新,上拉加载)
     *
     *  使用方法:(可设置type类型,默认是下拉上拉都有)
     *      1.  直接initWithType创建,然后将它的scrollView赋值,别忘了在使用它的ScrollView 或者 VC的dealloc
     *          中调用这个 deallocWithCloseConnect 方法
     *
     *  Created by 覃俊涵 on 13-9-18. All rights reserved.
     **/
    
    #import <UIKit/UIKit.h>
    #import "SRSlimeView.h"
    
    typedef enum{
        WaterRefreshTypeRefreshAndLoadMore,//含下拉上拉(default)
        WaterRefreshTypeOnlyRefresh,       //仅下拉刷新
        WaterRefreshTypeOnlyLoadMore,      //仅加载更多
        WaterRefreshTypeNone
    }WaterViewType;
    
    @protocol WaterRefreshDelegate;
    @protocol WaterLoadMoreDelegate;
    
    @interface WaterRefreshLoadMoreView : UIView
    
    @property (nonatomic, weak) UIScrollView *scrollView;
    @property (nonatomic, assign) WaterViewType type;
    
    // 水下拉的view
    @property (nonatomic, weak) UIView *waterRefreshView;
    // 上拉的view
    @property (nonatomic, strong) UIView *loadMoreView;
    
    // 水滴中央的图片样式
    @property (nonatomic, strong) UIImageView *refleshView;
    // 刷新提示字时 前方显示的 图片样式
    @property (nonatomic, strong) UIImageView *refreshRemindPicView;
    
    // refresh上的提示label
    @property (nonatomic, strong) UILabel *refreshRemind;
    // loadMore上的提示label
    @property (nonatomic, strong) UILabel *loadMoreRemind;
    
    // loadMore转圈时显示的文字,比如 "加载中..",没有设置则转动图样居中显示
    @property (nonatomic, strong) NSString *loadMoreIndicatorWord;
    
    @property (nonatomic, weak) id <WaterRefreshDelegate>   refreshDelegate;
    @property (nonatomic, weak) id <WaterLoadMoreDelegate>  loadMoreDelegate;
    @property (nonatomic, assign, readonly) BOOL isRefreshing;
    @property (nonatomic, assign, readonly) BOOL isLoadingMore;
    
    // initial method
    - (id)initWithWithType:(WaterViewType)type;
    
    // !你需要在使用它的ScrollView 或者 VC的dealloc中调用这个方法
    - (void)deallocWithCloseConnect;
    /*w
     start: 自动开始水滴下拉刷新自动开始,另一种是靠你手去拖动触发
     end  : 结束水滴下拉刷新并显示提示动画,请传入提示语,你可能会想提示:"刷新成功",
     可指定提示图片
     */
    - (void)startRefreshWithExpansion;
    - (void)startRefreshWithExpansionWithoutDelegate;
    - (void)endRefreshWithRemindsWords:(NSString *)remind remindImage:(UIImage *)remindImage;
    
    /*
     start: 自动开始上拉加载,另一种是靠手去上拉
     end  : 停止上拉加载,可给予提示
     */
    - (void)startLoadingMoreExpansion;
    - (void)startLoadingMoreExpansionWithOutDelegate;
    - (void)endLoadingMoreWithRemind:(NSString *)remind;
    
    // 禁掉loadMore的上拉加载功能,ban为YES时提示语默认为“没有更多内容”
    - (void)banFunctionOfStartLoadMore:(BOOL)ban remind:(NSString *)remind;
    
    - (void)setWaterRefreshColor:(UIColor*)color;
    @end
    
    @protocol WaterRefreshDelegate <NSObject>
    // 水滴下拉刷新的代理方法
    - (void)slimeRefreshStartRefresh:(WaterRefreshLoadMoreView*)refreshView;
    - (void)slimeRefreshEndRefresh:(WaterRefreshLoadMoreView *)refreshView;
    @end
    
    @protocol WaterLoadMoreDelegate <NSObject>
    
    @optional
    // 加载更多的代理方法
    - (void)loadMoreViewStartLoad:(WaterRefreshLoadMoreView*)refreshView;
    - (void)loadMoreViewEndLoad:(WaterRefreshLoadMoreView *)refreshView;
    @end
    WaterRefreshLoadMoreView.h
    //
    //  WaterRefreshLoadMoreView.m
    //  shiyanforwaterfresh
    //
    //  Created by 俊涵 on 13-9-19.
    //  Copyright (c) 2013年 俊涵. All rights reserved.
    //
    
    #import "WaterRefreshLoadMoreView.h"
    #import "SRSlimeView.h"
    #import <QuartzCore/QuartzCore.h>
    
    #define KEYPATH_CONTENTOFFSET       @"contentOffset"
    #define KEYPATH_CONTENTSIZE         @"contentSize"
    
    #define STRING_LOADMORE             @"加载更多"
    #define STRING_NOMORE               @"没有更多内容"
    
    #define HEIGHT_DEFAULT              40.0f
    #define DURIATION_ANIMATE           0.2f
    #define DURIATION_SHOWNOMORE        1.5f
    #define TAG_LOADMORE_INDICATOR      200
    #define kRefreshImageWidth          20.0f
    #define kDistanceFromRemind         10.0f
    
    static int scrollViewObservanceContext;
    static int scrollViewContentSizeContext;
    
    typedef enum {
        FooterViewStateNormal,
        FooterViewStateNormalPullling,
        FooterViewStateLoadingMore
    }FooterViewState;
    
    @interface WaterRefreshLoadMoreView()
    {
        UIImageView     *_refleshView;
        SRSlimeView     *_slime;
    }
    
    @property (nonatomic, assign) FooterViewState footerState;
    
    @property (nonatomic, strong) SRSlimeView *slime;
    @property (nonatomic, strong) UIActivityIndicatorView *loadMoreActivityView;
    
    @property (nonatomic, assign) BOOL closeLoadMore;
    @property (nonatomic, assign) BOOL endAnimation;
    @property (nonatomic, assign) BOOL endRefreshWithRemind;
    @property (nonatomic, assign) BOOL broken;
    @property (nonatomic, assign) BOOL slimeMissWhenGoingBack;
    @property (nonatomic, assign) BOOL lastDragScroll;
    @property (nonatomic, assign) BOOL isHasMoreContent;
    
    @property (nonatomic, assign) CGFloat upInset;
    @property (nonatomic, strong) NSString *refreshRemindWord;
    @property (nonatomic, strong) NSString *loadMoreRemindWord;
    
    @property (nonatomic, strong) UITapGestureRecognizer *gesture;
    
    @end
    
    @implementation WaterRefreshLoadMoreView {
        UIActivityIndicatorView *_activityIndicatorView;
        CGFloat     _oldLength;
        BOOL        _unmissSlime;
        CGFloat     _dragingHeight;
    }
    
    - (id)initWithFrame:(CGRect)frame
    {
        self = [self initWithHeight:HEIGHT_DEFAULT];
        return self;
    }
    
    - (id)initWithWithType:(WaterViewType)type
    {
        self = [self initWithHeight:HEIGHT_DEFAULT];
        self.type = type;
        return self;
    }
    
    - (id)initWithHeight:(CGFloat)height
    {
        CGRect frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, height);
        self = [super initWithFrame:frame];
        if (self) {
            // slime
            _slime = [[SRSlimeView alloc] initWithFrame:self.bounds];
            _slime.startPoint = CGPointMake(frame.size.width / 2, height / 2);
            [self addSubview:_slime];
            [_slime setPullApartTarget:self
                                action:@selector(pullApart:)];
            // 刷新图样
            _refleshView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"waterRefreshLoadMore_refresh"]];
            _refleshView.center = _slime.startPoint;
            _refleshView.bounds = CGRectMake(0.0f, 0.0f, kRefreshImageWidth, kRefreshImageWidth);
            [self addSubview:_refleshView];
            // indicator
            _activityIndicatorView = [[UIActivityIndicatorView alloc]
                                      initWithActivityIndicatorStyle:
                                      UIActivityIndicatorViewStyleGray];
            _activityIndicatorView.center = _slime.startPoint;
            [self addSubview:_activityIndicatorView];
            // refreshRemind
            self.refreshRemind = [[UILabel alloc] initWithFrame:_slime.frame];
            [self addSubview:self.refreshRemind];
            self.refreshRemind.backgroundColor = [UIColor clearColor];
            self.refreshRemind.textAlignment = NSTextAlignmentCenter;
            self.refreshRemind.textColor = [UIColor grayColor];
            self.refreshRemind.font = [UIFont systemFontOfSize:13.0f];
            self.refreshRemind.hidden = YES;
            // refreshRemindPicView
            self.refreshRemindPicView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, kRefreshImageWidth, kRefreshImageWidth)];
            [self addSubview:self.refreshRemindPicView];
            self.refreshRemindPicView.hidden = YES;
            // 设置拖拽临界点的高度
            _dragingHeight = height;
            self.slimeMissWhenGoingBack = NO;
            self.waterRefreshView = self;
        }
        return self;
    }
    
    - (void)setWaterRefreshColor:(UIColor*)color
    {
        [_activityIndicatorView setColor:color];
        self.refreshRemind.textColor = color;
     //   _slime.bodyColor = color;
    }
    
    - (void)didMoveToSuperview
    {
        [super didMoveToSuperview];
        if ([self.superview isKindOfClass:[UIScrollView class]]) {
            _scrollView = (id)[self superview];
            if (self.type == WaterRefreshTypeRefreshAndLoadMore || self.type == WaterRefreshTypeOnlyLoadMore) {
                [self addLoadMoreView];
            }
            self.isHasMoreContent = YES;
            // config frame
            CGRect rect = self.frame;
            rect.origin.y = rect.size.height ? -rect.size.height : -_dragingHeight;
            rect.size.width = _scrollView.frame.size.width;
            self.frame = rect;
            // inset
            UIEdgeInsets inset = self.scrollView.contentInset;
            inset.top = _upInset;
            self.scrollView.contentInset = inset;
            [self.scrollView addObserver:self forKeyPath:KEYPATH_CONTENTOFFSET options:0 context:&scrollViewObservanceContext];
            [self.scrollView addObserver:self forKeyPath:KEYPATH_CONTENTSIZE options:0 context:&scrollViewContentSizeContext];
            // configLoadMoreHide
            [self configLoadMoreHide];
        }else if (!self.superview) {
            self.scrollView = nil;
        }
    }
    
    - (void)addLoadMoreView
    {
        // add loadmore
        CGFloat maxTop = self.scrollView.frame.size.height > self.scrollView.contentSize.height ? self.scrollView.frame.size.height : self.scrollView.contentSize.height;
        self.loadMoreView = [[UIView alloc] initWithFrame:CGRectMake(0, maxTop, [UIScreen mainScreen].bounds.size.width, HEIGHT_DEFAULT)];
        [self.scrollView addSubview:self.loadMoreView];
        self.loadMoreView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
        self.loadMoreActivityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
        self.loadMoreActivityView.tag = TAG_LOADMORE_INDICATOR;
        [self.loadMoreView addSubview:self.loadMoreActivityView];
        self.loadMoreActivityView.center = CGPointMake(self.loadMoreView.frame.size.width / 2, self.loadMoreView.frame.size.height / 2);
        [self showLoadMoreRemind:STRING_LOADMORE];
        // config loadMoreRemind
        self.loadMoreRemind = [[UILabel alloc] initWithFrame:self.loadMoreView.bounds];
        self.loadMoreRemind.backgroundColor = [UIColor clearColor];
        self.loadMoreRemind.font = [UIFont systemFontOfSize:12.0f];
        self.loadMoreRemind.textColor = [UIColor grayColor];
        self.loadMoreRemind.textAlignment = NSTextAlignmentCenter;
        [self.loadMoreView addSubview:self.loadMoreRemind];
        //self.loadMoreRemind.hidden = NO;
        [self showLoadMoreRemind:STRING_LOADMORE];
        // gesture
        self.gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(loadMoreActionByClick)];
        [self.loadMoreView addGestureRecognizer:self.gesture];
        self.footerState = FooterViewStateNormal;
        [self configLoadMoreHide];
    }
    
    - (void)loadMoreActionByClick
    {
        [self scrollViewDataSourceDidStartLoadingMore:self.scrollView];
    }
    
    - (void)dealloc
    {
        [self clearObservance];
    }
    
    - (void)deallocWithCloseConnect  // TODO :换成更好的办法
    {
        [self clearObservance];
    }
    
    - (void)clearObservance
    {
        [self.scrollView removeObserver:self forKeyPath:KEYPATH_CONTENTOFFSET context:&scrollViewObservanceContext];
        [self.scrollView removeObserver:self forKeyPath:KEYPATH_CONTENTSIZE context:&scrollViewContentSizeContext];
        self.scrollView = nil;
    }
    
    - (void)removeFromSuperview
    {
        [NSObject cancelPreviousPerformRequestsWithTarget:self];
        [super removeFromSuperview];
    }
    
    #pragma mark - setters And getter
    
    - (void)setScrollView:(UIScrollView *)scrollView
    {
        if (_scrollView != scrollView) {
            _scrollView = scrollView;
            if (self.superview) {
                [self.loadMoreView removeFromSuperview];
                self.loadMoreView = nil;
                [self removeFromSuperview];
            }
            [self.scrollView addSubview:self];
        }
    }
    
    - (void)setType:(WaterViewType)type
    {
        if (self.type == type) {
            return;
        }
        if (self.type != WaterRefreshTypeNone) {
            [self.scrollView removeObserver:self forKeyPath:KEYPATH_CONTENTOFFSET context:&scrollViewObservanceContext];
            [self.scrollView removeObserver:self forKeyPath:KEYPATH_CONTENTSIZE context:&scrollViewContentSizeContext];
        }
        _type = type;
        _isLoadingMore = NO;
        [self setFooterState:FooterViewStateNormal];
        self.closeLoadMore = NO;
        // 如果切换类型之前动画还未结束
        if (self.endAnimation == NO) {
            self.endAnimation = YES;
        }
        self.endRefreshWithRemind = NO;
        [self endRefreshWithRemindsWords:@"" remindImage:nil];
        [self endLoadingMoreWithRemind:@""];
        [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(collapse) object:nil];
        [self backStateOfScrollView];
        if (type == WaterRefreshTypeRefreshAndLoadMore || type == WaterRefreshTypeOnlyRefresh) {
            self.hidden = NO;
            self.loadMoreView.hidden = NO;
            UIScrollView *scrollView = self.scrollView;
            self.scrollView = nil; //clear
            self.scrollView = scrollView;
        } else if (type == WaterRefreshTypeOnlyLoadMore) {
            self.loadMoreView.hidden = NO;
            self.hidden = YES;
            UIScrollView *scrollView = self.scrollView;
            self.scrollView = nil; //clear
            self.scrollView = scrollView;
        } else if(type == WaterRefreshTypeNone) {
            self.hidden = YES;
            self.loadMoreView.hidden = YES;
        }
    }
    
    - (void)backStateOfScrollView
    {
        UIEdgeInsets inset = self.scrollView.contentInset;
        inset.top = _upInset;
        inset.bottom = 0.0f;
        self.scrollView.contentInset = inset;
    }
    
    - (void)setFrame:(CGRect)frame
    {
        [super setFrame:frame];
        if (_slime.state == SRSlimeStateNormal) {
            _slime.frame = CGRectMake(0.0f, 0.0f, frame.size.width, frame.size.height);
            _slime.startPoint = CGPointMake(frame.size.width / 2, _dragingHeight / 2);
        }
        _refleshView.center = _slime.startPoint;
        _activityIndicatorView.center = _slime.startPoint;
    }
    
    - (void)setUpInset:(CGFloat)upInset
    {
        _upInset = upInset;
        UIEdgeInsets inset = _scrollView.contentInset;
        inset.top = _upInset;
        _scrollView.contentInset = inset;
    }
    
    - (void)setSlimeMissWhenGoingBack:(BOOL)slimeMissWhenGoingBack
    {
        _slimeMissWhenGoingBack = slimeMissWhenGoingBack;
        if (!slimeMissWhenGoingBack) {
            _slime.alpha = 1;
        }else {
            CGPoint p = _scrollView.contentOffset;
            self.alpha = -(p.y + _upInset) / _dragingHeight;
        }
    }
    
    #pragma mark - Scroll handle
    
    - (void)scrollViewDidScroll
    {
        CGPoint offset = _scrollView.contentOffset;
        CGRect rect = self.frame;
        // 下拉刷新
        if (self.type == WaterRefreshTypeRefreshAndLoadMore || self.type == WaterRefreshTypeOnlyRefresh) {
            if (offset.y <= - _dragingHeight - _upInset) {
                // 处于拉伸变形的状态
                rect.origin.y = offset.y + _upInset;
                rect.size.height = -offset.y;
                rect.size.height = ceilf(rect.size.height);
                self.frame = rect; //special setFrame
                if (!self.isRefreshing) {
                    [_slime setNeedsDisplay];
                }
                if (!_broken) {
                    float l = -(offset.y + _dragingHeight + _upInset);
                    if (l <= _oldLength) {
                        // 往回的时候
                        l = MIN(distansBetween(_slime.startPoint, _slime.toPoint), l);
                        CGPoint ssp = _slime.startPoint;
                        _slime.toPoint = CGPointMake(ssp.x, ssp.y + l);
                        CGFloat pf = (1.0f - l / _slime.viscous) * (1.0f - kStartTo) + kStartTo;
                        _refleshView.layer.transform = CATransform3DMakeScale(pf, pf, 1);
                    }else if (self.scrollView.isDragging) {
                        // 手拽着往下拉伸的时候
                        CGPoint ssp = _slime.startPoint;
                        _slime.toPoint = CGPointMake(ssp.x, ssp.y + l);
                        CGFloat pf = (1.0f - l / _slime.viscous) * (1.0f - kStartTo) + kStartTo;
                        _refleshView.layer.transform = CATransform3DMakeScale(pf, pf, 1);
                    }
                    _oldLength = l;
                }
                if (self.alpha != 1.0f) self.alpha = 1.0f; //拉出来显示的时候可能 alpha不为1
            }else if (offset.y < -_upInset) {
                rect.origin.y = -_dragingHeight;
                rect.size.height = _dragingHeight;
                self.frame = rect;
                [_slime setNeedsDisplay];
                _slime.toPoint = _slime.startPoint;
                if (_slimeMissWhenGoingBack)
                    self.alpha = -(offset.y + _upInset) / _dragingHeight;
            }
            if (self.isRefreshing && self.broken == NO) {
                // 配合适应inset避免 使用 tableview的话 section位置浮动错误
                UIEdgeInsets inset = _scrollView.contentInset;
                CGFloat offsetmath = MAX(_scrollView.contentOffset.y * -1, 0);
                offsetmath = MIN(offsetmath, HEIGHT_DEFAULT);
                inset.top = offsetmath;
                _scrollView.contentInset = inset;
            }
        }
        if ((self.type == WaterRefreshTypeRefreshAndLoadMore || self.type == WaterRefreshTypeOnlyLoadMore) && self.closeLoadMore == NO) {
            // 上拉
            if (self.footerState == FooterViewStateNormal) {
                if (self.scrollView.isDragging && [self offsetFromBottom:self.scrollView] > self.loadMoreView.frame.size.height + 5) {
                    [self setFooterState:FooterViewStateNormalPullling];
                    if (self.isHasMoreContent == NO) {
                    } else {
                        [self scrollViewDataSourceDidStartLoadingMore:self.scrollView];
                    }
                }
            } else if (self.footerState == FooterViewStateNormalPullling) {
                if (self.scrollView.isDragging && [self offsetFromBottom:self.scrollView] < self.frame.size.height + 5) {
                    [self setFooterState:FooterViewStateNormal];
                }
            } else if (self.footerState == FooterViewStateLoadingMore) {
            }
        }
    }
    
    - (void)scrollViewDidEndDraging
    {
        // 下拉刷新
        if (self.type == WaterRefreshTypeRefreshAndLoadMore || self.type == WaterRefreshTypeOnlyRefresh) {
            if (_broken) {
                self.broken = NO;
                if (self.isRefreshing) {
                    [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
                    [UIView animateWithDuration:DURIATION_ANIMATE animations:^{
                        UIEdgeInsets inset = _scrollView.contentInset;
                        inset.top = _upInset + _dragingHeight;
                        _scrollView.contentInset = inset;
                    } completion:^(BOOL finished) {
                    }];
                }
            }
        }
        // 上拉
        if ((self.type == WaterRefreshTypeRefreshAndLoadMore || self.type == WaterRefreshTypeOnlyLoadMore) && self.closeLoadMore == NO) {
            if (self.footerState == FooterViewStateNormalPullling) {
                if (self.isHasMoreContent == NO) {
                } else {
                    [self scrollViewDataSourceDidStartLoadingMore:self.scrollView];
                }
            }
        }
    }
    
    #pragma mark - loadMore
    
    - (void)relayoutLoadMoreViewAndInset
    {
        if (self.closeLoadMore == YES) {
            return;
        }
        CGFloat max = self.scrollView.contentSize.height < self.scrollView.frame.size.height ? self.scrollView.frame.size.height - self.scrollView.contentSize.height : 0;
        UIEdgeInsets inset = self.scrollView.contentInset;
        inset.bottom = max + self.loadMoreView.frame.size.height;
        self.scrollView.contentInset = inset;
        CGFloat footerViewTop = MAX(self.scrollView.frame.size.height, self.scrollView.contentSize.height);
        self.loadMoreView.frame = CGRectMake(0, footerViewTop, self.loadMoreView.frame.size.width, self.loadMoreView.frame.size.height);
    }
    
    - (void)configLoadMoreHide
    {
        if (self.type == WaterRefreshTypeRefreshAndLoadMore || self.type == WaterRefreshTypeOnlyLoadMore) {
            if (self.scrollView.contentSize.height < self.scrollView.frame.size.height) {
                self.loadMoreView.hidden = YES;
                self.closeLoadMore = YES;
                UIEdgeInsets inset = self.scrollView.contentInset;
                inset.bottom = 0.0f;
                self.scrollView.contentInset = inset;
            } else {
                self.loadMoreView.hidden = YES;
                self.closeLoadMore = YES;
                UIEdgeInsets inset = self.scrollView.contentInset;
                inset.bottom = self.loadMoreView.frame.size.height;
                self.scrollView.contentInset = inset;
                self.loadMoreView.hidden = NO;
                self.closeLoadMore = NO;
            }
        }
    }
    
    - (void)startLoadingMoreExpansion
    {
        [self scrollViewDataSourceDidStartLoadingMore:self.scrollView];
    }
    
    - (void)startLoadingMoreExpansionWithOutDelegate
    {
        [self scrollViewDataSourceDidStartLoadingMoreWithOutDelegate:self.scrollView];
    }
    
    - (void)endLoadingMoreWithRemind:(NSString *)remind
    {
        if (self.type == WaterRefreshTypeNone || self.type == WaterRefreshTypeOnlyRefresh) {
            return;
        }
        if (_isLoadingMore) {
            self.loadMoreRemindWord = remind;
            [self safeStopLoadingMore:self.scrollView];
        }
    }
    
    - (void)safeStartLoadingMore:(UIScrollView *)scrollView
    {
        if (!_isLoadingMore) {
            _isLoadingMore = YES;
        } else {
            return;
        }
        [self endRefreshWithRemindsWords:nil remindImage:nil];
        [self setFooterState:FooterViewStateLoadingMore];
        self.gesture.enabled = NO;
        self.loadMoreView.hidden = NO;
        [self showLoadMoreRemind:@""]; //清空
        [self.loadMoreActivityView startAnimating];
        // config 转动时提示
        [self configIndicatorPositionWithWord:self.loadMoreIndicatorWord];
        self.loadMoreRemind.alpha = 0.45f;
        // cofig animate with indicatorword
        NSTimeInterval animateDuration = 0.7f;
        [UIView animateWithDuration:animateDuration animations:^{
            self.loadMoreRemind.alpha = 1.0f;
        }];
        CAKeyframeAnimation *aniamtion = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
        aniamtion.values = [NSArray arrayWithObjects:
                            [NSValue valueWithCATransform3D:
                             CATransform3DRotate(CATransform3DMakeScale(0.01, 0.01, 0.1),
                                                 -M_PI, 0, 0, 1)],
                            [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.6, 1.6, 1)],
                            [NSValue valueWithCATransform3D:CATransform3DIdentity], nil];
        aniamtion.keyTimes = [NSArray arrayWithObjects:
                              [NSNumber numberWithFloat:0],
                              [NSNumber numberWithFloat:0.6],
                              [NSNumber numberWithFloat:1], nil];
        aniamtion.timingFunctions = [NSArray arrayWithObjects:
                                     [CAMediaTimingFunction functionWithName:
                                      kCAMediaTimingFunctionEaseInEaseOut],
                                     [CAMediaTimingFunction functionWithName:
                                      kCAMediaTimingFunctionEaseInEaseOut],
                                     nil];
        aniamtion.duration = animateDuration;
        self.loadMoreActivityView.layer.transform = CATransform3DIdentity;
        [self.loadMoreActivityView.layer addAnimation:aniamtion forKey:@""];
        
    }
    
    - (void)safeStopLoadingMore:(UIScrollView *)scrollView
    {
        if (!_isLoadingMore) {
            return;
        }
        [UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
        [UIView animateWithDuration:0.2f animations:^{
            self.loadMoreActivityView.layer.transform = CATransform3DRotate(CATransform3DMakeScale(0.01f, 0.01f, 0.1f), -M_PI, 0, 0, 1);
            self.loadMoreRemind.alpha = 0.2f;
        } completion:^(BOOL finished) {
            [self.loadMoreActivityView stopAnimating];
            self.loadMoreActivityView.layer.transform = CATransform3DRotate(CATransform3DMakeScale(1.0f, 1.0f, 1.0f), M_PI, 0, 0, 1);
            self.loadMoreRemind.alpha = 1.0f;
            [self relayoutLoadMoreViewAndInset];
            if (self.isHasMoreContent) {
                if (self.loadMoreRemindWord) {
                    //错误提示语
                    [self showLoadMoreRemind:self.loadMoreRemindWord];
                    [self performSelector:@selector(backToLoadMoreRemind) withObject:nil afterDelay:1.0f];
                } else {
                    [self showLoadMoreRemind:STRING_LOADMORE];
                    _isLoadingMore = NO;
                    [self setFooterState:FooterViewStateNormal];
                    self.gesture.enabled = YES;
                    if ([self.loadMoreDelegate respondsToSelector:@selector(loadMoreViewEndLoad:)]) {
                        [self.loadMoreDelegate loadMoreViewEndLoad:self];
                    }
                }
            } else {
                if (self.loadMoreRemindWord) {
                    if ([self.loadMoreRemindWord isEqualToString:@""]) {
                        self.loadMoreRemindWord = STRING_NOMORE;
                    }
                    [self showLoadMoreRemind:self.loadMoreRemindWord];
                } else {
                    [self showNoContentRemind];
                }
                [self performSelector:@selector(setInsetBottomAnimateToZeroAndCallDelegate:) withObject:[NSNumber numberWithBool:YES] afterDelay:DURIATION_SHOWNOMORE];
            }
        }];
    }
    
    - (void)setInsetBottomAnimateToZeroAndCallDelegate:(NSNumber *)callDelegate
    {
        [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
        [UIView animateWithDuration:DURIATION_ANIMATE animations:^{
            [self setInsetBottomToZero];
        } completion:^(BOOL finished) {
            _isLoadingMore = NO;
            [self setFooterState:FooterViewStateNormal];
            if (self.isHasMoreContent) {
                self.gesture.enabled = YES;
            }
            if (callDelegate.boolValue) {
                if ([self.loadMoreDelegate respondsToSelector:@selector(loadMoreViewEndLoad:)]) {
                    [self.loadMoreDelegate loadMoreViewEndLoad:self];
                }
            };
        }];
        [UIView commitAnimations];
    }
    
    - (void)setInsetBottomToZero
    {
        UIEdgeInsets currentInsets = self.scrollView.contentInset;
        currentInsets.bottom = 0;
        self.scrollView.contentInset = currentInsets;
    }
    
    - (void)scrollViewDataSourceDidStartLoadingMore:(UIScrollView *)scrollView
    {
        if (!_isLoadingMore) {
            [self safeStartLoadingMore:scrollView];
            if ([self.loadMoreDelegate respondsToSelector:@selector(loadMoreViewStartLoad:)]) {
                [self.loadMoreDelegate loadMoreViewStartLoad:self];
            }
        }
    }
    
    - (void)scrollViewDataSourceDidStartLoadingMoreWithOutDelegate:(UIScrollView *)scrollView
    {
        [self safeStartLoadingMore:scrollView];
    }
    
    - (void)scrollViewDataSourceDidFinishLoadingMore:(UIScrollView *)scrollView
    {
        [self safeStopLoadingMore:scrollView];
    }
    
    - (CGFloat)offsetFromBottom:(UIScrollView *)scrollView
    {
        CGFloat change = scrollView.contentSize.height < scrollView.frame.size.height ? 0 :  scrollView.contentSize.height - scrollView.frame.size.height;
        return  scrollView.contentOffset.y - change;
    }
    
    - (void)showNoContentRemind
    {
        self.loadMoreRemind.hidden = NO;
        [self showLoadMoreRemind:STRING_NOMORE];
    }
    
    - (void)showLoadMoreRemind:(NSString *)remindword
    {
        self.loadMoreActivityView.hidden = YES;
        self.loadMoreRemind.hidden = NO;
        self.loadMoreRemind.text = remindword;
        self.loadMoreRemind.center = CGPointMake(self.loadMoreView.frame.size.width / 2, self.loadMoreView.frame.size.height / 2);
        self.loadMoreRemindWord = nil; //clear
    }
    
    - (void)backToLoadMoreRemind
    {
        UILabel *label = self.loadMoreRemind;
        [UIView animateWithDuration:0.3f animations:^{
            label.alpha = 0.0f;
        } completion:^(BOOL finished) {
            [self showLoadMoreRemind:STRING_LOADMORE];
            [UIView animateWithDuration:0.3f animations:^{
                label.alpha = 1.0f;
                self.gesture.enabled = YES;
                _isLoadingMore = NO;
                [self setFooterState:FooterViewStateNormal];
                if ([self.loadMoreDelegate respondsToSelector:@selector(loadMoreViewEndLoad:)]) {
                    [self.loadMoreDelegate loadMoreViewEndLoad:self];
                }
            }];
        }];
    }
    
    - (void)banFunctionOfStartLoadMore:(BOOL)ban remind:(NSString *)remind
    {
        if (ban) {
            self.gesture.enabled = NO;
            self.isHasMoreContent = NO;
            if (remind) {
                self.loadMoreRemind.text = remind;
                [self endLoadingMoreWithRemind:remind];
            } else {
                self.loadMoreRemind.text = STRING_NOMORE;
                [self endLoadingMoreWithRemind:STRING_NOMORE];
            }
            [self performSelector:@selector(setInsetBottomAnimateToZeroAndCallDelegate:) withObject:[NSNumber numberWithBool:NO] afterDelay:DURIATION_SHOWNOMORE];
        } else {
            self.gesture.enabled = YES;
            self.isHasMoreContent = YES;
            if (!_isLoadingMore) {
                [self showLoadMoreRemind:STRING_LOADMORE];
            }
        }
    }
    
    - (void)configIndicatorPositionWithWord:(NSString *)word
    {
        if (word && ![word isEqualToString:@""]) {
            // 如果有提供的文字就做左偏移
            self.loadMoreRemind.hidden = NO;
            self.loadMoreRemind.alpha = 1.0f;
            self.loadMoreRemind.text = word;
            CGSize size = [word sizeWithFont:self.loadMoreRemind.font constrainedToSize:CGSizeMake(self.loadMoreView.bounds.size.width, MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping];
            CGRect rect = self.loadMoreRemind.frame;
            rect.size.width = size.width;
            rect.size.height = size.height;
            self.loadMoreRemind.frame = rect;
            self.loadMoreRemind.center = CGPointMake(self.loadMoreView.frame.size.width / 2, self.loadMoreView.frame.size.height / 2);
            self.loadMoreActivityView.center = CGPointMake(self.loadMoreRemind.frame.origin.x - kDistanceFromRemind, self.loadMoreActivityView.center.y);
            [self alignmentWithView:self.loadMoreActivityView lable:self.loadMoreRemind distance:kDistanceFromRemind totalWidth:self.scrollView.frame.size.width];
        } else {
            //还原
            self.loadMoreRemind.hidden = YES;
            UIActivityIndicatorView *indicator = (UIActivityIndicatorView *)[self.loadMoreView viewWithTag:TAG_LOADMORE_INDICATOR];
            indicator.center = CGPointMake(self.loadMoreView.frame.size.width / 2, self.loadMoreView.frame.size.height / 2);
            self.loadMoreRemind.center = indicator.center;
        }
    }
    
    - (void)alignmentWithView:(UIView *)view lable:(UILabel *)label distance:(CGFloat)distance totalWidth:(CGFloat)totalWidth
    {
        CGFloat viewWidths = view.frame.size.width + distance + label.frame.size.width;
        CGFloat left = (totalWidth - viewWidths) / 2;
        view.center = CGPointMake(left + view.frame.size.width / 2 , view.center.y);
        label.center = CGPointMake(view.center.x + view.frame.size.width /2 + distance + label.frame.size.width / 2, label.center.y);
    }
    
    #pragma mark - refresh
    
    - (void)setIsRefreshing:(BOOL)isRefreshing
    {
        if (_isRefreshing == isRefreshing) {
            return;
        }
        _isRefreshing = isRefreshing;
        if (_isRefreshing) {
            [self endLoadingMoreWithRemind:nil];
            [_activityIndicatorView.layer removeAllAnimations];
            [_activityIndicatorView startAnimating];
            CAKeyframeAnimation *aniamtion = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
            aniamtion.values = [NSArray arrayWithObjects:
                                [NSValue valueWithCATransform3D:
                                 CATransform3DRotate(CATransform3DMakeScale(0.01, 0.01, 0.1),
                                                     -M_PI, 0, 0, 1)],
                                [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.6, 1.6, 1)],
                                [NSValue valueWithCATransform3D:CATransform3DIdentity], nil];
            aniamtion.keyTimes = [NSArray arrayWithObjects:
                                  [NSNumber numberWithFloat:0],
                                  [NSNumber numberWithFloat:0.6],
                                  [NSNumber numberWithFloat:1], nil];
            aniamtion.timingFunctions = [NSArray arrayWithObjects:
                                         [CAMediaTimingFunction functionWithName:
                                          kCAMediaTimingFunctionEaseInEaseOut],
                                         [CAMediaTimingFunction functionWithName:
                                          kCAMediaTimingFunctionEaseInEaseOut],
                                         nil];
            aniamtion.duration = 0.7;
            aniamtion.delegate = self;
            _activityIndicatorView.layer.transform = CATransform3DIdentity;
            [_activityIndicatorView.layer addAnimation:aniamtion
                                                forKey:@""];
            _refleshView.hidden = YES;
            if (!_unmissSlime){
                _slime.state = SRSlimeStateMiss;
            }else {
                _unmissSlime = NO;
            }
        }else {
            // 刷新结束
            [_activityIndicatorView stopAnimating];
            [_activityIndicatorView.layer removeAllAnimations];
            _refleshView.layer.transform = CATransform3DIdentity;
            [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
            [UIView animateWithDuration:0.35f animations:^{
                UIEdgeInsets inset = _scrollView.contentInset;
                inset.top = _upInset;
                _scrollView.contentInset = inset;
                if (_scrollView.contentOffset.y == -_upInset &&
                    _slimeMissWhenGoingBack) {
                    self.alpha = 0.0f;
                }
            } completion:^(BOOL finished) {
                _broken = NO;
                _slime.hidden = NO;
                _refleshView.hidden = NO;
                self.refreshRemind.text = @"";
                self.refreshRemindPicView.hidden = YES;
            }];
        }
    }
    
    - (void)startRefreshWithExpansion
    {
        if (self.type == WaterRefreshTypeOnlyLoadMore || self.type == WaterRefreshTypeNone) {
            return;
        }
        if (self.isRefreshing) {
            return;
        }
        [UIView animateWithDuration:DURIATION_ANIMATE animations:^() {
            UIEdgeInsets inset = _scrollView.contentInset;
            inset.top = _upInset + _dragingHeight;
            _scrollView.contentInset = inset;
            [_scrollView setContentOffset:CGPointMake(_scrollView.contentOffset.x,
                                                      -_scrollView.contentInset.top)
                                 animated:NO];
        }];
        [self startRefresh];
    }
    
    -(void)startRefreshWithExpansionWithoutDelegate{
        if (self.type == WaterRefreshTypeOnlyLoadMore || self.type == WaterRefreshTypeNone) {
            return;
        }
        if (self.isRefreshing) {
            return;
        }
        [UIView animateWithDuration:DURIATION_ANIMATE animations:^() {
            UIEdgeInsets inset = _scrollView.contentInset;
            inset.top = _upInset + _dragingHeight;
            _scrollView.contentInset = inset;
            [_scrollView setContentOffset:CGPointMake(_scrollView.contentOffset.x,
                                                      -_scrollView.contentInset.top)
                                 animated:NO];
        } completion:^(BOOL finished) {
        }];
        self.isRefreshing = YES;
    }
    
    - (void)startRefresh
    {
        self.isRefreshing = YES;
        if ([self.refreshDelegate respondsToSelector:@selector(slimeRefreshStartRefresh:)]) {
            [self.refreshDelegate slimeRefreshStartRefresh:self];
        }
    }
    
    - (void)pullApart:(WaterRefreshLoadMoreView*)refreshView
    {
        self.broken = YES;
        _unmissSlime = YES;
        [self startRefresh];
    }
    
    - (void)endRefreshWithRemindsWords:(NSString *)remind remindImage:(UIImage *)remindImage
    {
        if (self.type == WaterRefreshTypeOnlyLoadMore || self.type == WaterRefreshTypeNone ) {
            return;
        }
        if (self.isRefreshing && self.endRefreshWithRemind == NO) {
            self.refreshRemindWord = remind;
            self.refreshRemindPicView.image = remindImage;
            self.endRefreshWithRemind = YES;
            if (self.endAnimation == YES) {
                [self restore];
            }
        }
    }
    
    - (void)showRemindWordAndClear;
    {
        if (!self.refreshRemindWord || [self.refreshRemindWord isEqualToString:@""]) {
            [self collapse];
            return;
        }
        self.refreshRemind.hidden = NO;
        self.refreshRemind.text = self.refreshRemindWord;
        self.refreshRemindWord = nil;
        [self performSelector:@selector(collapse) withObject:nil afterDelay:0.5f];
        
    }
    
    - (void)configRefreshPicViewPositionWithWord:(NSString *)word
    {
        if (word && ![word isEqualToString:@""]) {
            // 如果有提供的文字就做左偏移
            //self.refreshRemindPicView.hidden = NO;
            self.refreshRemindPicView.alpha = 1.0f;
            CGSize size = [word sizeWithFont:self.refreshRemind.font constrainedToSize:CGSizeMake(self.bounds.size.width, MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping];
            CGRect rect = self.refreshRemind.frame;
            rect.size.width = size.width;
            rect.size.height = size.height;
            self.refreshRemind.frame = rect;
            self.refreshRemind.center = _slime.startPoint;
            self.refreshRemindPicView.center = CGPointMake(self.refreshRemind.frame.origin.x - kDistanceFromRemind, self.refreshRemind.center.y);
            [self alignmentWithView:self.refreshRemindPicView lable:self.refreshRemind distance:kDistanceFromRemind totalWidth:self.scrollView.frame.size.width];
        } else {
            //还原
            //self.refreshRemindPicView.hidden = NO;
            self.refreshRemindPicView.alpha = 1.0f;
            self.refreshRemindPicView.center = _slime.startPoint;
        }
    }
    
    - (void)restore
    {
        _oldLength = 0.0f;
        _slime.toPoint = _slime.startPoint;
        [_activityIndicatorView.layer removeAllAnimations];
        [UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
        [UIView animateWithDuration:0.3f animations:^{
            _activityIndicatorView.layer.transform = CATransform3DRotate(CATransform3DMakeScale(0.01f, 0.01f, 0.1f), -M_PI, 0, 0, 1);
        } completion:^(BOOL finished)
         {
             [self relayoutLoadMoreViewAndInset];
             if (self.refreshRemindPicView.image) {
                 self.refreshRemindPicView.hidden = NO;
                 [self configRefreshPicViewPositionWithWord:self.refreshRemindWord];
             } else {
                 [self alignmentWithView:nil lable:self.refreshRemind distance:0.0f totalWidth:self.scrollView.frame.size.width];
             }
             if (self.refreshRemindWord) {
                 self.refreshRemind.hidden = NO;
                 [self showRemindWordAndClear];
             } else {
                 [self collapse];
             }
         }];
    }
    
    - (void)collapse
    {
        if (_isRefreshing == NO) {
            return;
        }
        [self setIsRefreshing:NO];
        self.endRefreshWithRemind = NO;
        _slime.state = SRSlimeStateNormal;
        if ([self.refreshDelegate respondsToSelector:@selector(slimeRefreshEndRefresh:)]) {
            [self.refreshDelegate slimeRefreshEndRefresh:self];
        }
    }
    
    #pragma mark - Observer handle
    
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
        if (context == &scrollViewObservanceContext) {
            // handle change
            if ([keyPath isEqualToString:KEYPATH_CONTENTOFFSET]) {
                [self scrollViewDidScroll];
                if (self.scrollView.dragging == YES && self.lastDragScroll == NO) {
                    self.lastDragScroll = YES;
                } else if (self.scrollView.dragging == NO && self.lastDragScroll == YES) {
                    self.lastDragScroll = NO;
                    [self scrollViewDidEndDraging];
                }
            }
        }
        if (context == &scrollViewContentSizeContext) {
            if ([keyPath isEqualToString:KEYPATH_CONTENTSIZE]) {
                [self configLoadMoreHide];
                [self relayoutLoadMoreViewAndInset];
            }
        }
    }
    
    #pragma mark - Animation Delegate
    
    - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
    {
        self.endAnimation = YES;
        if (self.endRefreshWithRemind == YES) {
            self.endRefreshWithRemind = NO;
            self.endAnimation = NO;
            [self restore];
        }
    }
    
    - (void)animationDidStart:(CAAnimation *)anim
    {
        self.endAnimation = NO;
    }
    
    @end
    WaterRefreshLoadMoreView.m

    源码用的图片:

    使用源码:

    //
    //  ViewController.m
    //  Refresh
    //
    //  Created by YouXianMing on 14/11/21.
    //  Copyright (c) 2014年 YouXianMing. All rights reserved.
    //
    
    #import "ViewController.h"
    #import "WaterRefreshLoadMoreView.h"
    
    @interface ViewController ()
    
    @property (nonatomic, strong) UITableView               *tableView;
    @property (nonatomic, strong) WaterRefreshLoadMoreView  *refreshLoadMoreView;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 64, 320, 400)
                                                      style:UITableViewStylePlain];
        [self.view addSubview:self.tableView];
        
        _refreshLoadMoreView = [[WaterRefreshLoadMoreView alloc] initWithWithType:WaterRefreshTypeOnlyRefresh];
        _refreshLoadMoreView.scrollView = self.tableView;
    }
    
    - (void)dealloc {
        [_refreshLoadMoreView deallocWithCloseConnect];
    }
    
    @end
  • 相关阅读:
    Python MySQL(SQL语句的补充3)
    Python MySQL(pymysql的使用day1)
    Python MySQL(SQL语句的补充2)
    Python MySQL(对外键使用方法的补充)
    Python MySQL(学习SQL语句)
    Python MySQL数据库的基本使用
    关于http响应内容压缩的一点小积累。
    同一账号,后一用户登录,前一个用户则被踢掉
    对序列化的学习。
    MySQL 函数积累
  • 原文地址:https://www.cnblogs.com/YouXianMing/p/4113939.html
Copyright © 2011-2022 走看看