上拉加载下拉刷新控件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.6CGPoint 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:_startPointradius:startRadiusstartAngle:angleS + angle1endAngle:angleS + M_PI*2 - angle1clockwise:YES];[path addQuadCurveToPoint:ep1controlPoint:mp1];angleS = atan2f(_startPoint.y - _toPoint.y,_startPoint.x - _toPoint.x);[path addArcWithCenter:_toPointradius:endRadiusstartAngle:angleS + M_PI/2endAngle:angleS + M_PI*3/2clockwise:YES];[path addQuadCurveToPoint:sp1controlPoint: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 pathUIBezierPath *path = [self bodyPath:startRadiusend:endRadiuspercent: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:_actionwithObject:self];
#pragma clang diagnostic pop[self performSelector:@selector(scaling)withObject:nilafterDelay:kAnimationIntervalinModes:[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:startRadiusend:endRadiuspercent: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:nilafterDelay:kAnimationIntervalinModes:[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:selfselector:@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;
/*wstart: 自动开始水滴下拉刷新自动开始,另一种是靠你手去拖动触发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.0fstatic 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:selfaction:@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];// refreshRemindself.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;// refreshRemindPicViewself.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 frameCGRect rect = self.frame;rect.origin.y = rect.size.height ? -rect.size.height : -_dragingHeight;rect.size.width = _scrollView.frame.size.width;self.frame = rect;// insetUIEdgeInsets 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 loadmoreCGFloat 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 loadMoreRemindself.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];// gestureself.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; //clearself.scrollView = scrollView;} else if (type == WaterRefreshTypeOnlyLoadMore) {self.loadMoreView.hidden = NO;self.hidden = YES;UIScrollView *scrollView = self.scrollView;self.scrollView = nil; //clearself.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 setFrameif (!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 indicatorwordNSTimeInterval 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:aniamtionforKey:@""];_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 changeif ([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

转载于:https://www.cnblogs.com/YouXianMing/p/4113939.html

上拉加载下拉刷新控件WaterRefreshLoadMoreView相关推荐

  1. php微信小程序向下滑动,微信小程序功能实现:上滑加载下拉刷新

    本篇文章给大家带来的内容是关于微信小程序功能实现:上滑加载下拉刷新,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 之前谈到文章列表的数据加载,是一次性全部加载,这样是不友好的.这章介 ...

  2. ionic上拉加载-下拉刷新

    ionic上拉加载-下拉刷新 1.上拉加载 <ion-infinite-scroll on-infinite="loadOlderStories()" distance=&q ...

  3. Mint-ui中loadmore(上拉加载下拉刷新)组件在ios中滑动会触发点击事件的解决方法...

    bug说明: Mint-ui中loadmore(上拉加载下拉刷新)组件 在 使用fastclick的情况下 ,在ios设备中滑动会触发点击事件: 解决方法: 我是按需引入,去项目中找到loadmore ...

  4. php mescroll,mescroll.js上拉加载下拉刷新组件使用详解

    本文实例为大家分享了上拉加载下拉刷新组件mescroll.js的具体代码,供大家参考,具体内容如下 使用注意事项: 1.引入的时候出问题及时看官方给出的解决方案(基本上都必须看): 2.react中一 ...

  5. 教你如何使用SwipeRefreshLayout来构建一个上拉加载下拉刷新框架

    前言: 基本上所以的移动端应用都有Listview(当然RecyclerView也一样),那必不可少的都会嵌入一个上拉加载下拉刷新的功能.这样能大大的减少用户的流量消耗,同样对于用户也有更好的用户体验 ...

  6. ios 上拉加载 下拉刷新

    在一款 App应用中有的时候会用到上拉加载下拉刷新的功能,本人觉得SVPullToRefresh很好用(可以用在UIScrollView上,包括UITableview和UICollectionView ...

  7. 上拉加载下拉刷新了解下

    2019独角兽企业重金招聘Python工程师标准>>> 老样子,我们先,哦不,今天我们直接上思路,没有效果图,真的没有 我们依旧从界面及逻辑两块进行分析 1.界面上,只分成简单的两块 ...

  8. 图片自动轮播+上拉加载下拉刷新+侧滑菜单+小圆点

    //效果图如下 //添加权限 <uses-permission android:name="android.permission.INTERNET"></uses ...

  9. uniapp 自定义上拉加载下拉刷新组件

    介绍 该组件是结合uview框架写的,主要结合了里面的u-loadmore组件,可配置下拉刷新加载圈的颜色及背景色,暂无数据时的图等,突出的特点就是通过设置组件的高度,适配刘海屏iPhone,且支持嵌 ...

  10. Android 智能上拉加载下拉刷新框架之SmartRefreshLayout

    1.说明: SmartRefreshLayout的目标是打造一个强大,稳定,成熟的下拉刷新框架,并集成各种的炫酷.多样.实用.美观的Header和Footer.它不只是支持所有的View,还支持多层嵌 ...

最新文章

  1. 科研团队如何探索商业化落地?这家语音AI公司用十年科学试验打了样
  2. 一文读懂并发与并行,同步与异步阻塞
  3. Spark安装与学习
  4. 找出重复最多的字符php,javascript获取重复次数最多的字符_javascript技巧
  5. 并发编程-03线程安全性之原子性(Atomic包)及原理分析
  6. XCTF WEB weak_auth
  7. php opcache 详解
  8. oracle嵌套三层循环语句,在存储过程中执行3种oracle循环语句
  9. 苹果WWDC 2019最全剧透抢先看:iOS夜间模式要来了!
  10. ASP.NET Core管道深度剖析
  11. RigUp 数据库暴露7.6万份美国能源行业文件
  12. 100套精品PPT模板免费拿!以后再也不用怕老板叫你制作PPT了
  13. 腾讯云通信音视频通话最小化悬浮小窗
  14. 程序员如何缓解眼睛疲劳酸痛症状?
  15. 定位弹窗软件----找到真凶并做后续防御
  16. Python爬取王者荣耀官网图片
  17. 期权最新高频行情数据
  18. SSH Tunneling
  19. github上如何删除自己的仓库
  20. JavaScript内存相关初了解:堆栈、引擎、闭包隐患

热门文章

  1. backtrace函数
  2. CentOS配置history记录每个用户执行过的命令
  3. 中小企业应该将云存储用于主数据吗?
  4. 惠州物联网产业规模 明年争取达400亿元
  5. Ubuntu安装nagios步骤
  6. C++深度探索系列:智能指针(Smart Pointer) [一] (转)
  7. Xgboost通俗理解和总结
  8. 服务消费(Ribbon)
  9. 复变函数、运筹学与概率论知识总结
  10. mysql中计算日期整数差