Initial commit
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// JHRefreshAmazingAniView.h
|
||||
// JHRefresh
|
||||
//
|
||||
// Created by Jiahai on 14-9-17.
|
||||
// Copyright (c) 2014年 Jiahai. All rights reserved.
|
||||
//
|
||||
|
||||
#import "JHRefreshAniBaseView.h"
|
||||
|
||||
@interface JHRefreshAmazingAniView : JHRefreshAniBaseView
|
||||
{
|
||||
UIImageView *_aniImgView;
|
||||
}
|
||||
@end
|
||||
@@ -0,0 +1,146 @@
|
||||
//
|
||||
// JHRefreshAmazingAniView.m
|
||||
// JHRefresh
|
||||
//
|
||||
// Created by Jiahai on 14-9-17.
|
||||
// Copyright (c) 2014年 Jiahai. All rights reserved.
|
||||
//
|
||||
|
||||
#import "JHRefreshAmazingAniView.h"
|
||||
#import "JHRefreshMacro.h"
|
||||
#import "UIView+JHExtension.h"
|
||||
|
||||
@implementation JHRefreshAmazingAniView
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
|
||||
// Initialization code
|
||||
|
||||
_aniImgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:JHRefreshSrcName(@"JHdown_anim__0001.png")]];
|
||||
_aniImgView.frame = CGRectMake(0, 0, 50, 50);
|
||||
_aniImgView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin;
|
||||
[self addSubview:_aniImgView];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
|
||||
_aniImgView.center = CGPointMake(self.jh_width*0.5, self.jh_height*0.5);
|
||||
}
|
||||
|
||||
/*
|
||||
// Only override drawRect: if you perform custom drawing.
|
||||
// An empty implementation adversely affects performance during animation.
|
||||
- (void)drawRect:(CGRect)rect
|
||||
{
|
||||
// Drawing code
|
||||
}
|
||||
*/
|
||||
|
||||
#pragma mark - JHRefreshViewDelegate
|
||||
|
||||
/**
|
||||
* 下拉时的动画
|
||||
*/
|
||||
- (void)refreshViewAniToBePulling
|
||||
{
|
||||
|
||||
}
|
||||
/**
|
||||
* 变成普通状态时的动画
|
||||
*/
|
||||
- (void)refreshViewAniToBeNormal
|
||||
{
|
||||
[_aniImgView stopAnimating];
|
||||
}
|
||||
/**
|
||||
* 刷新开始
|
||||
*/
|
||||
- (void)refreshViewBeginRefreshing
|
||||
{
|
||||
if(!_aniImgView.animationImages)
|
||||
{
|
||||
// _aniImgView.animationImages = [NSArray arrayWithObjects:
|
||||
// [UIImage imageNamed:JHRefreshSrcName(@"dropdown_loading_01.png")],
|
||||
// [UIImage imageNamed:JHRefreshSrcName(@"dropdown_loading_02.png")],
|
||||
//
|
||||
// nil];
|
||||
|
||||
NSMutableArray *images = [[NSMutableArray alloc] init];
|
||||
|
||||
for (int i = 1; i <= 63; i ++) {
|
||||
|
||||
if (i < 10) {
|
||||
[images addObject:[UIImage imageNamed:[NSString stringWithFormat:@"neves000%d",i]]];
|
||||
|
||||
}else{
|
||||
[images addObject:[UIImage imageNamed:[NSString stringWithFormat:@"neves00%d",i]]];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_aniImgView.animationImages=images;
|
||||
|
||||
_aniImgView.animationDuration = 2.0;
|
||||
_aniImgView.animationRepeatCount = 0;
|
||||
|
||||
}
|
||||
|
||||
//刷新开始时,设置aniImageView的宽高
|
||||
_aniImgView.jh_width = _aniImgView.jh_height = JHRefreshViewHeight;
|
||||
[_aniImgView startAnimating];
|
||||
}
|
||||
/**
|
||||
* 刷新结束
|
||||
*
|
||||
* @param result 刷新结果
|
||||
*/
|
||||
- (void)refreshViewEndRefreshing:(JHRefreshResult)result
|
||||
{
|
||||
|
||||
}
|
||||
/**
|
||||
* 拖拽到对应的位置
|
||||
*
|
||||
* @param pos 位置,范围:1 ~ JHRefreshViewHeight
|
||||
*/
|
||||
- (void)refreshViewPullingToPosition:(NSInteger)pos
|
||||
{
|
||||
if(pos == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
CGPoint center = _aniImgView.center;
|
||||
|
||||
_aniImgView.jh_width = _aniImgView.jh_height = pos;
|
||||
|
||||
_aniImgView.center = center;
|
||||
NSString*name=nil;
|
||||
|
||||
name =@"neves0063.png";
|
||||
//name = [NSString stringWithFormat:@"dropdown_anim__000%d.png",(int)pos];
|
||||
|
||||
// if (pos<10) {
|
||||
// name = [NSString stringWithFormat:@"neves000%d.png",(int)pos];
|
||||
// }else{
|
||||
// name = [NSString stringWithFormat:@"neves00%d.png",(int)pos];
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
//NSLog(@"pos%ld",(long)pos);
|
||||
|
||||
_aniImgView.image = [UIImage imageNamed:name];
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// JHRefreshAniBaseView.h
|
||||
// JHRefresh
|
||||
//
|
||||
// Created by Jiahai on 14-9-15.
|
||||
// Copyright (c) 2014年 Jiahai. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "JHRefreshViewDelegate.h"
|
||||
#import "JHRefreshConfig.h"
|
||||
|
||||
@interface JHRefreshAniBaseView : UIView<JHRefreshViewDelegate>
|
||||
@property (nonatomic, assign) JHRefreshViewType refreshViewType;
|
||||
@property (nonatomic, assign) NSInteger refreshViewID;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,74 @@
|
||||
//
|
||||
// JHRefreshAniBaseView.m
|
||||
// JHRefresh
|
||||
//
|
||||
// Created by Jiahai on 14-9-15.
|
||||
// Copyright (c) 2014年 Jiahai. All rights reserved.
|
||||
//
|
||||
|
||||
#import "JHRefreshAniBaseView.h"
|
||||
#import "JHRefreshHeaderView.h"
|
||||
#import "JHRefreshFooterView.h"
|
||||
#import "UIView+JHExtension.h"
|
||||
|
||||
@implementation JHRefreshAniBaseView
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
// Initialization code
|
||||
|
||||
self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)willMoveToSuperview:(UIView *)newSuperview
|
||||
{
|
||||
[super willMoveToSuperview:newSuperview];
|
||||
|
||||
self.jh_width = newSuperview.jh_width;
|
||||
self.jh_height = newSuperview.jh_height;
|
||||
|
||||
if([newSuperview isKindOfClass:[JHRefreshHeaderView class]])
|
||||
{
|
||||
self.refreshViewType = JHRefreshViewTypeHeader;
|
||||
}
|
||||
else if([newSuperview isKindOfClass:[JHRefreshFooterView class]])
|
||||
{
|
||||
self.refreshViewType = JHRefreshViewTypeFooter;
|
||||
}
|
||||
|
||||
self.refreshViewID = ((JHRefreshBaseView *)newSuperview).ID;
|
||||
}
|
||||
|
||||
#pragma mark - JHRefreshViewDelegate
|
||||
- (void)refreshViewAniToBePulling
|
||||
{
|
||||
|
||||
}
|
||||
- (void)refreshViewAniToBeNormal
|
||||
{
|
||||
|
||||
}
|
||||
- (void)refreshViewBeginRefreshing
|
||||
{
|
||||
|
||||
}
|
||||
- (void)refreshViewEndRefreshing:(JHRefreshResult)result
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// Only override drawRect: if you perform custom drawing.
|
||||
// An empty implementation adversely affects performance during animation.
|
||||
- (void)drawRect:(CGRect)rect
|
||||
{
|
||||
// Drawing code
|
||||
}
|
||||
*/
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// JHRefreshCommonAniView.h
|
||||
// JHRefresh
|
||||
//
|
||||
// Created by Jiahai on 14-9-15.
|
||||
// Copyright (c) 2014年 Jiahai. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "JHRefreshMacro.h"
|
||||
#import "JHRefreshAniBaseView.h"
|
||||
|
||||
@interface JHRefreshCommonAniView : JHRefreshAniBaseView
|
||||
{
|
||||
UIImageView *_arrowImgView;
|
||||
UIImageView* _leftImgView;
|
||||
UIActivityIndicatorView *_activityView;
|
||||
UILabel *_statusLabel;
|
||||
UILabel *_lastUpdateTimeLabel;
|
||||
}
|
||||
@end
|
||||
@@ -0,0 +1,211 @@
|
||||
//
|
||||
// JHRefreshCommonAniView.m
|
||||
// JHRefresh
|
||||
//
|
||||
// Created by Jiahai on 14-9-15.
|
||||
// Copyright (c) 2014年 Jiahai. All rights reserved.
|
||||
//
|
||||
|
||||
#import "JHRefreshCommonAniView.h"
|
||||
#import "UIView+JHExtension.h"
|
||||
#import "JHRefreshConfig.h"
|
||||
#define ROT 3.14159265358979323846264338327950288
|
||||
#define JHRefreshLabelTextColor JHRGBA(150,150,150,1)
|
||||
|
||||
@implementation JHRefreshCommonAniView
|
||||
|
||||
NSString *const JHRefreshHeaderStatusTextNormal = @"下拉刷新";
|
||||
NSString *const JHRefreshHeaderStatusTextPulling = @"松开既可刷新";
|
||||
NSString *const JHRefreshHeaderStatusTextRefreshing = @"正在刷新。。。";
|
||||
NSString *const JHRefreshHeaderStatusTextSuccess = @"刷新成功";
|
||||
NSString *const JHRefreshHeaderStatusTextFailure = @"刷新失败";
|
||||
|
||||
NSString *const JHRefreshFooterStatusTextNormal = @"上拉加载更多";
|
||||
NSString *const JHRefreshFooterStatusTextPulling = @"松开既可加载";
|
||||
NSString *const JHRefreshFooterStatusTextRefreshing = @"正在加载。。。";
|
||||
NSString *const JHRefreshFooterStatusTextSuccess = @"加载成功";
|
||||
NSString *const JHRefreshFooterStatusTextFailure = @"加载失败";
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
// Initialization code
|
||||
|
||||
_statusLabel = [[UILabel alloc] init];
|
||||
_statusLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;
|
||||
_statusLabel.font = [UIFont boldSystemFontOfSize:13];
|
||||
_statusLabel.textColor = JHRefreshLabelTextColor;
|
||||
_statusLabel.backgroundColor = [UIColor clearColor];
|
||||
_statusLabel.textAlignment = NSTextAlignmentCenter;
|
||||
[self addSubview:_statusLabel];
|
||||
_statusLabel.text = JHRefreshHeaderStatusTextNormal;
|
||||
|
||||
_lastUpdateTimeLabel = [[UILabel alloc] init];
|
||||
_lastUpdateTimeLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;
|
||||
_lastUpdateTimeLabel.font = [UIFont boldSystemFontOfSize:13];
|
||||
_lastUpdateTimeLabel.textColor = JHRefreshLabelTextColor;
|
||||
_lastUpdateTimeLabel.backgroundColor = [UIColor clearColor];
|
||||
_lastUpdateTimeLabel.textAlignment = NSTextAlignmentCenter;
|
||||
[self addSubview:_lastUpdateTimeLabel];
|
||||
_lastUpdateTimeLabel.text = [JHRefreshConfig getLastUpdateTimeWithRefreshViewID:self.refreshViewID];
|
||||
|
||||
// _arrowImgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:JHRefreshSrcName(@"dropdown_loading_01")]];
|
||||
_arrowImgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@""]];
|
||||
_arrowImgView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleRightMargin;
|
||||
[self addSubview:_arrowImgView];
|
||||
|
||||
|
||||
// _leftImgView=[[UIImageView alloc]initWithImage:[UIImage imageNamed:JHRefreshSrcName(@"dropdown_loading_01")]];
|
||||
// _leftImgView.bounds=_arrowImgView.bounds;
|
||||
// _leftImgView.autoresizingMask=_arrowImgView.autoresizingMask;
|
||||
// [self addSubview:_leftImgView];
|
||||
|
||||
_activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
|
||||
_activityView.bounds = _arrowImgView.bounds;
|
||||
_activityView.autoresizingMask = _arrowImgView.autoresizingMask;
|
||||
[self addSubview:_activityView];
|
||||
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)willMoveToSuperview:(UIView *)newSuperview
|
||||
{
|
||||
[super willMoveToSuperview:newSuperview];
|
||||
|
||||
if(self.refreshViewType == JHRefreshViewTypeFooter)
|
||||
{
|
||||
_statusLabel.text = JHRefreshFooterStatusTextNormal;
|
||||
_arrowImgView.transform = CGAffineTransformMakeRotation(M_PI);
|
||||
_lastUpdateTimeLabel.hidden = YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
|
||||
// 状态
|
||||
_statusLabel.frame = CGRectMake(0, 0, self.jh_width, self.jh_height*0.5);
|
||||
|
||||
// 时间
|
||||
_lastUpdateTimeLabel.frame = CGRectMake(0, _statusLabel.jh_height, _statusLabel.jh_width, _statusLabel.jh_height);
|
||||
|
||||
_arrowImgView.center = CGPointMake(self.jh_width*0.5 - 100, self.jh_height*0.5);
|
||||
_activityView.center = _arrowImgView.center;
|
||||
}
|
||||
|
||||
#pragma mark - JHRefreshViewDelegate
|
||||
- (void)refreshViewAniToBePulling
|
||||
{
|
||||
switch (self.refreshViewType) {
|
||||
case JHRefreshViewTypeHeader:
|
||||
{
|
||||
_statusLabel.text = JHRefreshHeaderStatusTextPulling;
|
||||
|
||||
[UIView animateWithDuration:JHRefreshFastAnimationDuration animations:^{
|
||||
_arrowImgView.transform = CGAffineTransformMakeRotation(M_PI);
|
||||
}];
|
||||
}
|
||||
break;
|
||||
case JHRefreshViewTypeFooter:
|
||||
{
|
||||
_statusLabel.text = JHRefreshFooterStatusTextPulling;
|
||||
|
||||
[UIView animateWithDuration:JHRefreshFastAnimationDuration animations:^{
|
||||
_arrowImgView.transform = CGAffineTransformIdentity;
|
||||
}];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
- (void)refreshViewAniToBeNormal
|
||||
{
|
||||
switch (self.refreshViewType) {
|
||||
case JHRefreshViewTypeHeader:
|
||||
{
|
||||
_statusLabel.text = JHRefreshHeaderStatusTextNormal;
|
||||
|
||||
[UIView animateWithDuration:JHRefreshFastAnimationDuration animations:^{
|
||||
_arrowImgView.transform = CGAffineTransformIdentity;
|
||||
}];
|
||||
}
|
||||
break;
|
||||
case JHRefreshViewTypeFooter:
|
||||
{
|
||||
_statusLabel.text = JHRefreshFooterStatusTextNormal;
|
||||
|
||||
[UIView animateWithDuration:JHRefreshFastAnimationDuration animations:^{
|
||||
_arrowImgView.transform = CGAffineTransformMakeRotation(2*ROT);
|
||||
}];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
- (void)refreshViewBeginRefreshing
|
||||
{
|
||||
switch (self.refreshViewType) {
|
||||
case JHRefreshViewTypeHeader:
|
||||
{
|
||||
_statusLabel.text = JHRefreshHeaderStatusTextRefreshing;
|
||||
}
|
||||
break;
|
||||
case JHRefreshViewTypeFooter:
|
||||
{
|
||||
_statusLabel.text = JHRefreshFooterStatusTextRefreshing;
|
||||
}
|
||||
break;
|
||||
}
|
||||
_arrowImgView.hidden = YES;
|
||||
[_activityView startAnimating];
|
||||
}
|
||||
|
||||
- (void)refreshViewEndRefreshing:(JHRefreshResult)result
|
||||
{
|
||||
switch (self.refreshViewType) {
|
||||
case JHRefreshViewTypeHeader:
|
||||
{
|
||||
switch (result) {
|
||||
case JHRefreshResultNone:
|
||||
_statusLabel.text = JHRefreshHeaderStatusTextNormal;
|
||||
break;
|
||||
case JHRefreshResultSuccess:
|
||||
{
|
||||
_statusLabel.text = JHRefreshHeaderStatusTextSuccess;
|
||||
}
|
||||
break;
|
||||
case JHRefreshResultFailure:
|
||||
{
|
||||
_statusLabel.text = JHRefreshHeaderStatusTextFailure;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
_arrowImgView.transform = CGAffineTransformIdentity;
|
||||
}
|
||||
break;
|
||||
case JHRefreshViewTypeFooter:
|
||||
{
|
||||
_statusLabel.text = JHRefreshHeaderStatusTextNormal;
|
||||
|
||||
_arrowImgView.transform = CGAffineTransformMakeRotation(M_PI);
|
||||
}
|
||||
break;
|
||||
}
|
||||
_lastUpdateTimeLabel.text = [JHRefreshConfig getLastUpdateTimeWithRefreshViewID:self.refreshViewID];
|
||||
[JHRefreshConfig updateLastUpdateTimeWithRefreshViewID:self.refreshViewID];
|
||||
[_activityView stopAnimating];
|
||||
_arrowImgView.hidden = NO;
|
||||
}
|
||||
|
||||
/*
|
||||
// Only override drawRect: if you perform custom drawing.
|
||||
// An empty implementation adversely affects performance during animation.
|
||||
- (void)drawRect:(CGRect)rect
|
||||
{
|
||||
// Drawing code
|
||||
}
|
||||
*/
|
||||
|
||||
@end
|
||||
|
After Width: | Height: | Size: 7.8 KiB |
|
After Width: | Height: | Size: 8.1 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 5.5 KiB |
|
After Width: | Height: | Size: 5.5 KiB |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 6.1 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
@@ -0,0 +1,11 @@
|
||||
//
|
||||
// JHRefresh.h
|
||||
// JHRefresh
|
||||
//
|
||||
// Created by Jiahai on 14-9-15.
|
||||
// Copyright (c) 2014年 Jiahai. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UIScrollView+JHRefresh.h"
|
||||
#import "JHRefreshCommonAniView.h"
|
||||
#import "JHRefreshAmazingAniView.h"
|
||||
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// JHRefreshBaseView.h
|
||||
// JHRefresh
|
||||
//
|
||||
// Created by Jiahai on 14-9-12.
|
||||
// Copyright (c) 2014年 Jiahai. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "JHRefreshAniBaseView.h"
|
||||
|
||||
typedef NS_ENUM(NSInteger, JHRefreshState) {
|
||||
JHRefreshStatePulling = 1,
|
||||
JHRefreshStateNormal,
|
||||
JHRefreshStateRefreshing
|
||||
};
|
||||
|
||||
@interface JHRefreshBaseView : UIView
|
||||
/**
|
||||
* App中有多个refreshView时,用以存放不同的配置信息,如:lastUpdateTime,也可不填
|
||||
*/
|
||||
@property (nonatomic, assign) NSInteger ID;
|
||||
|
||||
@property (nonatomic, weak, readonly) UIScrollView *scrollView;
|
||||
|
||||
@property (nonatomic, assign) JHRefreshState state;
|
||||
|
||||
@property (nonatomic, copy) void (^beginRefreshingBlock)();
|
||||
|
||||
@property (nonatomic, strong) JHRefreshAniBaseView<JHRefreshViewDelegate> *aniView;
|
||||
//@property (nonatomic, copy) void (^)
|
||||
|
||||
@property (nonatomic, readonly) BOOL refreshing;
|
||||
|
||||
+ (instancetype)createView;
|
||||
|
||||
- (void)endRefreshingWithResult:(JHRefreshResult)result;
|
||||
@end
|
||||
@@ -0,0 +1,180 @@
|
||||
//
|
||||
// JHRefreshBaseView.m
|
||||
// JHRefresh
|
||||
//
|
||||
// Created by Jiahai on 14-9-12.
|
||||
// Copyright (c) 2014年 Jiahai. All rights reserved.
|
||||
//
|
||||
|
||||
#import "JHRefreshBaseView.h"
|
||||
#import "JHRefreshConfig.h"
|
||||
#import "UIScrollView+JHExtension.h"
|
||||
#import "UIView+JHExtension.h"
|
||||
|
||||
@interface JHRefreshBaseView ()
|
||||
@property (nonatomic, assign) JHRefreshResult refreshResult; //刷新是否成功
|
||||
|
||||
/**
|
||||
* 正在刷新时设置contentInset的值,header设置Top,footer设置bottom
|
||||
*/
|
||||
- (void)setRefreshingContentInset;
|
||||
/**
|
||||
* 刷新完成后还原contentInset的值
|
||||
*/
|
||||
- (void)resumeContentInset;
|
||||
@end
|
||||
|
||||
@implementation JHRefreshBaseView
|
||||
|
||||
+ (instancetype)createView
|
||||
{
|
||||
return [[[self class] alloc] init];
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame
|
||||
{
|
||||
frame.size.height = JHRefreshViewHeight;
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
// Initialization code
|
||||
self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
|
||||
self.backgroundColor = [UIColor clearColor];
|
||||
|
||||
self.state = JHRefreshStateNormal;
|
||||
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setAniView:(JHRefreshAniBaseView<JHRefreshViewDelegate> *)aniView
|
||||
{
|
||||
if(_aniView)
|
||||
{
|
||||
[_aniView removeFromSuperview];
|
||||
}
|
||||
|
||||
[self addSubview:aniView];
|
||||
_aniView = aniView;
|
||||
}
|
||||
|
||||
- (void)willMoveToSuperview:(UIView *)newSuperview
|
||||
{
|
||||
[super willMoveToSuperview:newSuperview];
|
||||
|
||||
self.jh_width = newSuperview.jh_width;
|
||||
|
||||
[self.superview removeObserver:self forKeyPath:JHRefreshContentOffset];
|
||||
|
||||
[newSuperview addObserver:self forKeyPath:JHRefreshContentOffset options:NSKeyValueObservingOptionNew context:nil];
|
||||
|
||||
_scrollView = (UIScrollView *)newSuperview;
|
||||
|
||||
}
|
||||
|
||||
- (BOOL)refreshing
|
||||
{
|
||||
return self.state == JHRefreshStateRefreshing;
|
||||
}
|
||||
|
||||
- (void)setState:(JHRefreshState)state
|
||||
{
|
||||
//状态不改变什么都不做
|
||||
if(_state == state)
|
||||
return;
|
||||
|
||||
JHRefreshState oldState = _state;
|
||||
_state = state;
|
||||
|
||||
switch (oldState) {
|
||||
case JHRefreshStateNormal:
|
||||
{
|
||||
if(state == JHRefreshStatePulling)
|
||||
{
|
||||
//普通状态转为下拉状态
|
||||
[_aniView refreshViewAniToBePulling];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case JHRefreshStateRefreshing:
|
||||
{
|
||||
if(state == JHRefreshStateNormal)
|
||||
{
|
||||
//刷新状态转为普通状态
|
||||
[_aniView refreshViewEndRefreshing:_refreshResult];
|
||||
|
||||
switch (_refreshResult) {
|
||||
case JHRefreshResultNone:
|
||||
{
|
||||
[self resumeContentInset];
|
||||
[_aniView refreshViewAniToBeNormal];
|
||||
}
|
||||
break;
|
||||
case JHRefreshResultSuccess:
|
||||
case JHRefreshResultFailure:
|
||||
{
|
||||
//展示刷新结果,延时隐藏refreshView;
|
||||
dispatch_time_t delayInNanoSeconds =dispatch_time(DISPATCH_TIME_NOW, JHRefreshShowResultAnimationDuration * NSEC_PER_SEC);
|
||||
//延期执行
|
||||
dispatch_after(delayInNanoSeconds, dispatch_get_main_queue(), ^{
|
||||
[UIView animateWithDuration:JHRefreshSlowAnimationDuration animations:^{
|
||||
[self resumeContentInset];
|
||||
[_aniView refreshViewAniToBeNormal];
|
||||
}];
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case JHRefreshStatePulling:
|
||||
{
|
||||
if(state == JHRefreshStateNormal)
|
||||
{
|
||||
//下拉状态转为普通状态
|
||||
[_aniView refreshViewAniToBeNormal];
|
||||
}
|
||||
else if(state == JHRefreshStateRefreshing)
|
||||
{
|
||||
//下拉状态转为刷新状态
|
||||
|
||||
//
|
||||
[self setRefreshingContentInset];
|
||||
|
||||
[_aniView refreshViewBeginRefreshing];
|
||||
|
||||
//执行刷新block
|
||||
if(self.beginRefreshingBlock)
|
||||
self.beginRefreshingBlock();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)endRefreshingWithResult:(JHRefreshResult)result
|
||||
{
|
||||
self.refreshResult = result;
|
||||
self.state = JHRefreshStateNormal;
|
||||
}
|
||||
|
||||
- (void)setRefreshingContentInset
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
- (void)resumeContentInset
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
// Only override drawRect: if you perform custom drawing.
|
||||
// An empty implementation adversely affects performance during animation.
|
||||
- (void)drawRect:(CGRect)rect
|
||||
{
|
||||
// Drawing code
|
||||
}
|
||||
*/
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// JHRefreshConfig.h
|
||||
// JHRefresh
|
||||
//
|
||||
// Created by Jiahai on 14-9-12.
|
||||
// Copyright (c) 2014年 Jiahai. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "JHRefreshMacro.h"
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
typedef NS_ENUM(NSInteger, JHRefreshViewType) {
|
||||
JHRefreshViewTypeHeader = 1,
|
||||
JHRefreshViewTypeFooter
|
||||
};
|
||||
|
||||
/**
|
||||
* 刷新结果
|
||||
*/
|
||||
typedef NS_ENUM(NSInteger, JHRefreshResult) {
|
||||
/**
|
||||
* 不展示刷新结果,刷新结束直接隐藏
|
||||
*/
|
||||
JHRefreshResultNone = 0,
|
||||
/**
|
||||
* 展示刷新成功界面,延时隐藏
|
||||
*/
|
||||
JHRefreshResultSuccess,
|
||||
/**
|
||||
* 展示刷新失败界面,延时隐藏
|
||||
*/
|
||||
JHRefreshResultFailure
|
||||
};
|
||||
|
||||
|
||||
|
||||
extern const CGFloat JHRefreshViewHeight;
|
||||
extern const CGFloat JHRefreshFastAnimationDuration;
|
||||
extern const CGFloat JHRefreshSlowAnimationDuration;
|
||||
extern const CGFloat JHRefreshShowResultAnimationDuration;
|
||||
|
||||
|
||||
extern NSString *const JHRefreshContentOffset;
|
||||
extern NSString *const JHRefreshContentSize;
|
||||
|
||||
@interface JHRefreshConfig : NSObject
|
||||
|
||||
+ (NSString *)getLastUpdateTimeWithRefreshViewID:(NSInteger)ID;
|
||||
|
||||
+ (void)updateLastUpdateTimeWithRefreshViewID:(NSInteger)ID;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,75 @@
|
||||
//
|
||||
// JHRefreshConfig.m
|
||||
// JHRefresh
|
||||
//
|
||||
// Created by Jiahai on 14-9-12.
|
||||
// Copyright (c) 2014年 Jiahai. All rights reserved.
|
||||
//
|
||||
|
||||
#import "JHRefreshConfig.h"
|
||||
|
||||
const CGFloat JHRefreshViewHeight = 63.0;
|
||||
const CGFloat JHRefreshFastAnimationDuration = 0.2;
|
||||
const CGFloat JHRefreshSlowAnimationDuration = 0.4;
|
||||
const CGFloat JHRefreshShowResultAnimationDuration = 0.5;
|
||||
|
||||
|
||||
NSString *const JHRefreshContentOffset = @"contentOffset";
|
||||
NSString *const JHRefreshContentSize = @"contentSize";
|
||||
|
||||
NSString *const JHRefreshConfigKey = @"JHRefreshConfig";
|
||||
NSString *const JHRefreshLastUpdateTimeKey = @"JHRefreshLastUpdateTime";
|
||||
NSString *const JHRefreshLastUpdateTimeFormat = @"yyyy-MM-dd HH:mm";
|
||||
|
||||
/**
|
||||
* JHRefreshConfig的目录结构
|
||||
--NSUserDefaults
|
||||
|
|
||||
——JHRefreshConfigKey //JHRefresh所有的配置存储路径
|
||||
|
|
||||
|——JHRefreshLastUpdateTimeKey //lastUpdateTime配置存储路径
|
||||
*/
|
||||
|
||||
@implementation JHRefreshConfig
|
||||
|
||||
+ (NSString*)nowTimeString
|
||||
{
|
||||
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
|
||||
[dateFormatter setDateFormat:JHRefreshLastUpdateTimeFormat];
|
||||
return [NSString stringWithFormat:@"上次刷新:%@", [dateFormatter stringFromDate:[NSDate date]]];
|
||||
}
|
||||
|
||||
+ (NSString *)getLastUpdateTimeWithRefreshViewID:(NSInteger)ID
|
||||
{
|
||||
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
|
||||
NSDictionary *refreshDic = [userDefault objectForKey:JHRefreshConfigKey];
|
||||
NSString *time = [[refreshDic objectForKey:JHRefreshLastUpdateTimeKey] objectForKey:[NSString stringWithFormat:@"%@_%d",JHRefreshLastUpdateTimeKey,ID]];
|
||||
|
||||
if(!time)
|
||||
{
|
||||
return [[self class] nowTimeString];
|
||||
}
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
+ (void)updateLastUpdateTimeWithRefreshViewID:(NSInteger)ID
|
||||
{
|
||||
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
|
||||
NSMutableDictionary *refreshDic = [userDefault objectForKey:JHRefreshConfigKey];
|
||||
if(!refreshDic)
|
||||
{
|
||||
refreshDic = [NSMutableDictionary dictionary];
|
||||
}
|
||||
NSMutableDictionary *lastUpdateTimeDic = [refreshDic objectForKey:JHRefreshLastUpdateTimeKey];
|
||||
if(!lastUpdateTimeDic)
|
||||
{
|
||||
lastUpdateTimeDic = [NSMutableDictionary dictionary];
|
||||
}
|
||||
[lastUpdateTimeDic setObject:[[self class] nowTimeString] forKey:[NSString stringWithFormat:@"%@_%d",JHRefreshLastUpdateTimeKey,ID]];
|
||||
|
||||
[userDefault setObject:refreshDic forKey:JHRefreshConfigKey];
|
||||
[userDefault synchronize];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// JHRefreshFooterView.h
|
||||
// JHRefresh
|
||||
//
|
||||
// Created by Jiahai on 14-9-16.
|
||||
// Copyright (c) 2014年 Jiahai. All rights reserved.
|
||||
//
|
||||
|
||||
#import "JHRefreshBaseView.h"
|
||||
|
||||
@interface JHRefreshFooterView : JHRefreshBaseView
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,128 @@
|
||||
//
|
||||
// JHRefreshFooterView.m
|
||||
// JHRefresh
|
||||
//
|
||||
// Created by Jiahai on 14-9-16.
|
||||
// Copyright (c) 2014年 Jiahai. All rights reserved.
|
||||
//
|
||||
|
||||
#import "JHRefreshFooterView.h"
|
||||
#import "JHRefreshConfig.h"
|
||||
#import "UIView+JHExtension.h"
|
||||
#import "UIScrollView+JHExtension.h"
|
||||
|
||||
@implementation JHRefreshFooterView
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
// Initialization code
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)willMoveToSuperview:(UIView *)newSuperview
|
||||
{
|
||||
[super willMoveToSuperview:newSuperview];
|
||||
|
||||
[self.superview removeObserver:self forKeyPath:JHRefreshContentSize];
|
||||
|
||||
[newSuperview addObserver:self forKeyPath:JHRefreshContentSize options:NSKeyValueObservingOptionNew context:nil];
|
||||
|
||||
[self ajustFooterView];
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
|
||||
{
|
||||
if([keyPath isEqualToString:JHRefreshContentSize])
|
||||
{
|
||||
[self ajustFooterView];
|
||||
}
|
||||
|
||||
//正在刷新,直接返回
|
||||
if(self.state == JHRefreshStateRefreshing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if([keyPath isEqualToString:JHRefreshContentOffset])
|
||||
{
|
||||
[self changeStateWithContentOffset];
|
||||
|
||||
if([self.aniView respondsToSelector:@selector(refreshViewPullingToPosition:)])
|
||||
{
|
||||
NSInteger pos = self.scrollView.contentOffset.y + self.scrollView.jh_height - self.scrollView.jh_contentSizeHeight-self.scrollView.jh_contentInsetBottom;
|
||||
|
||||
//footerView不可见/全部显示后,直接返回
|
||||
if(pos <= 0 || pos > JHRefreshViewHeight)
|
||||
return;
|
||||
|
||||
[self.aniView refreshViewPullingToPosition:pos];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)changeStateWithContentOffset
|
||||
{
|
||||
CGFloat currentOffsetY = self.scrollView.contentOffset.y;
|
||||
CGFloat releaseToRefreshOffsetY = MAX(self.scrollView.jh_contentSizeHeight,self.scrollView.jh_height) - self.scrollView.jh_height + self.scrollView.jh_contentInsetBottom;
|
||||
|
||||
//footerView的顶端不可见时,直接返回
|
||||
if(currentOffsetY <= releaseToRefreshOffsetY)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
releaseToRefreshOffsetY += JHRefreshViewHeight;
|
||||
|
||||
if(self.scrollView.isDragging)
|
||||
{
|
||||
if(self.state == JHRefreshStateNormal && currentOffsetY>releaseToRefreshOffsetY)
|
||||
{
|
||||
self.state = JHRefreshStatePulling;
|
||||
}
|
||||
else if(self.state == JHRefreshStatePulling && currentOffsetY <= releaseToRefreshOffsetY)
|
||||
{
|
||||
self.state = JHRefreshStateNormal;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(self.state == JHRefreshStatePulling)
|
||||
{
|
||||
self.state = JHRefreshStateRefreshing;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 调整footerView的位置
|
||||
*/
|
||||
- (void)ajustFooterView
|
||||
{
|
||||
CGFloat contentSizeHeight = self.scrollView.jh_contentSizeHeight;
|
||||
CGFloat height = self.scrollView.jh_height;
|
||||
|
||||
self.jh_originY = MAX(height, contentSizeHeight);
|
||||
}
|
||||
|
||||
- (void)setRefreshingContentInset
|
||||
{
|
||||
self.scrollView.jh_contentInsetBottom += JHRefreshViewHeight;
|
||||
}
|
||||
|
||||
- (void)resumeContentInset
|
||||
{
|
||||
self.scrollView.jh_contentInsetBottom -= JHRefreshViewHeight;
|
||||
}
|
||||
|
||||
/*
|
||||
// Only override drawRect: if you perform custom drawing.
|
||||
// An empty implementation adversely affects performance during animation.
|
||||
- (void)drawRect:(CGRect)rect
|
||||
{
|
||||
// Drawing code
|
||||
}
|
||||
*/
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// JHRefreshHeaderView.h
|
||||
// JHRefresh
|
||||
//
|
||||
// Created by Jiahai on 14-9-15.
|
||||
// Copyright (c) 2014年 Jiahai. All rights reserved.
|
||||
//
|
||||
|
||||
#import "JHRefreshBaseView.h"
|
||||
|
||||
@interface JHRefreshHeaderView : JHRefreshBaseView
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,105 @@
|
||||
//
|
||||
// JHRefreshHeaderView.m
|
||||
// JHRefresh
|
||||
//
|
||||
// Created by Jiahai on 14-9-15.
|
||||
// Copyright (c) 2014年 Jiahai. All rights reserved.
|
||||
//
|
||||
|
||||
#import "JHRefreshHeaderView.h"
|
||||
#import "JHRefreshConfig.h"
|
||||
#import "UIScrollView+JHExtension.h"
|
||||
#import "UIView+JHExtension.h"
|
||||
|
||||
@implementation JHRefreshHeaderView
|
||||
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
// Initialization code
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)willMoveToSuperview:(UIView *)newSuperview
|
||||
{
|
||||
[super willMoveToSuperview:newSuperview];
|
||||
|
||||
self.jh_originY = -JHRefreshViewHeight;
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
|
||||
{
|
||||
if(self.state == JHRefreshStateRefreshing)
|
||||
return;
|
||||
|
||||
if([keyPath isEqualToString:JHRefreshContentOffset])
|
||||
{
|
||||
[self changeStateWithContentOffset];
|
||||
|
||||
if([self.aniView respondsToSelector:@selector(refreshViewPullingToPosition:)])
|
||||
{
|
||||
NSInteger pos = self.scrollView.contentOffset.y;
|
||||
|
||||
//headerView不可见/全部可见时,直接返回
|
||||
if(pos > 0 || pos < -JHRefreshViewHeight-self.scrollView.jh_contentInsetTop)
|
||||
return;
|
||||
|
||||
[self.aniView refreshViewPullingToPosition:abs((int)pos)-self.scrollView.jh_contentInsetTop];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)changeStateWithContentOffset
|
||||
{
|
||||
CGFloat currentOffsetY = self.scrollView.contentOffset.y;
|
||||
CGFloat releaseToRefreshOffsetY = - self.scrollView.jh_contentInsetTop;
|
||||
|
||||
//headerView的顶端不可见时,直接返回
|
||||
if(currentOffsetY>=releaseToRefreshOffsetY)
|
||||
return;
|
||||
|
||||
releaseToRefreshOffsetY -= self.jh_height;
|
||||
|
||||
if(self.scrollView.isDragging)
|
||||
{
|
||||
if(self.state == JHRefreshStateNormal && currentOffsetY < releaseToRefreshOffsetY)
|
||||
{
|
||||
//即将刷新
|
||||
self.state = JHRefreshStatePulling;
|
||||
}
|
||||
else if(self.state == JHRefreshStatePulling && currentOffsetY>=releaseToRefreshOffsetY)
|
||||
{
|
||||
//普通状态
|
||||
self.state = JHRefreshStateNormal;
|
||||
}
|
||||
}
|
||||
else if (self.state == JHRefreshStatePulling)
|
||||
{
|
||||
//开始刷新
|
||||
self.state = JHRefreshStateRefreshing;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setRefreshingContentInset
|
||||
{
|
||||
self.scrollView.jh_contentInsetTop += JHRefreshViewHeight;
|
||||
}
|
||||
|
||||
- (void)resumeContentInset
|
||||
{
|
||||
self.scrollView.jh_contentInsetTop -= JHRefreshViewHeight;
|
||||
}
|
||||
|
||||
/*
|
||||
// Only override drawRect: if you perform custom drawing.
|
||||
// An empty implementation adversely affects performance during animation.
|
||||
- (void)drawRect:(CGRect)rect
|
||||
{
|
||||
// Drawing code
|
||||
}
|
||||
*/
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// JHRefreshMacro.h
|
||||
// JHRefresh
|
||||
//
|
||||
// Created by Jiahai on 14-9-12.
|
||||
// Copyright (c) 2014年 Jiahai. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef JHRefresh_JHRefreshMacro_h
|
||||
#define JHRefresh_JHRefreshMacro_h
|
||||
|
||||
|
||||
#pragma mark - 通用
|
||||
#ifdef DEBUG
|
||||
#define JHLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
|
||||
#else
|
||||
#define JHLog(fmt, ...)
|
||||
#endif
|
||||
|
||||
#define JHRefreshBundleName @"JHRefresh.bundle"
|
||||
#define JHRefreshSrcName(file) ([JHRefreshBundleName stringByAppendingPathComponent:(file)])
|
||||
|
||||
|
||||
#pragma mark 颜色配置
|
||||
#define JHRGBA(r,g,b,a) [UIColor colorWithRed:(float)r/255.0f green:(float)g/255.0f blue:(float)b/255.0f alpha:a]
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,42 @@
|
||||
//
|
||||
// JHRefreshViewDelegate.h
|
||||
// JHRefresh
|
||||
//
|
||||
// Created by Jiahai on 14-9-15.
|
||||
// Copyright (c) 2014年 Jiahai. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "JHRefreshConfig.h"
|
||||
|
||||
@protocol JHRefreshViewDelegate <NSObject>
|
||||
|
||||
@required
|
||||
/**
|
||||
* 下拉时的动画
|
||||
*/
|
||||
- (void)refreshViewAniToBePulling;
|
||||
/**
|
||||
* 变成普通状态时的动画
|
||||
*/
|
||||
- (void)refreshViewAniToBeNormal;
|
||||
/**
|
||||
* 刷新开始
|
||||
*/
|
||||
- (void)refreshViewBeginRefreshing;
|
||||
/**
|
||||
* 刷新结束
|
||||
*
|
||||
* @param result 刷新结果
|
||||
*/
|
||||
- (void)refreshViewEndRefreshing:(JHRefreshResult)result;
|
||||
|
||||
@optional
|
||||
/**
|
||||
* 拖拽到对应的位置
|
||||
*
|
||||
* @param pos 位置,范围:1-JHRefreshViewHeight
|
||||
*/
|
||||
- (void)refreshViewPullingToPosition:(NSInteger)pos;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// UIScrollView+JHExtension.h
|
||||
// JHRefresh
|
||||
//
|
||||
// Created by Jiahai on 14-9-15.
|
||||
// Copyright (c) 2014年 Jiahai. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface UIScrollView (JHExtension)
|
||||
|
||||
@property (nonatomic, assign) CGFloat jh_contentInsetTop;
|
||||
@property (nonatomic, assign) CGFloat jh_contentInsetBottom;
|
||||
@property (nonatomic, assign) CGFloat jh_contentInsetLeft;
|
||||
@property (nonatomic, assign) CGFloat jh_contentInsetRight;
|
||||
@property (nonatomic, assign) CGFloat jh_contentSizeWidth;
|
||||
@property (nonatomic, assign) CGFloat jh_contentSizeHeight;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,75 @@
|
||||
//
|
||||
// UIScrollView+JHExtension.m
|
||||
// JHRefresh
|
||||
//
|
||||
// Created by Jiahai on 14-9-15.
|
||||
// Copyright (c) 2014年 Jiahai. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UIScrollView+JHExtension.h"
|
||||
|
||||
@implementation UIScrollView (JHExtension)
|
||||
#pragma mark - contentInset
|
||||
- (CGFloat)jh_contentInsetTop
|
||||
{
|
||||
return self.contentInset.top;
|
||||
}
|
||||
- (void)setJh_contentInsetTop:(CGFloat)jh_contentInsetTop
|
||||
{
|
||||
UIEdgeInsets inset = self.contentInset;
|
||||
inset.top = jh_contentInsetTop;
|
||||
self.contentInset = inset;
|
||||
}
|
||||
- (CGFloat)jh_contentInsetBottom
|
||||
{
|
||||
return self.contentInset.bottom;
|
||||
}
|
||||
- (void)setJh_contentInsetBottom:(CGFloat)jh_contentInsetBottom
|
||||
{
|
||||
UIEdgeInsets inset = self.contentInset;
|
||||
inset.bottom = jh_contentInsetBottom;
|
||||
self.contentInset = inset;
|
||||
}
|
||||
- (CGFloat)jh_contentInsetLeft
|
||||
{
|
||||
return self.contentInset.left;
|
||||
}
|
||||
- (void)setJh_contentInsetLeft:(CGFloat)jh_contentInsetLeft
|
||||
{
|
||||
UIEdgeInsets inset = self.contentInset;
|
||||
inset.left = jh_contentInsetLeft;
|
||||
self.contentInset = inset;
|
||||
}
|
||||
- (CGFloat)jh_contentInsetRight
|
||||
{
|
||||
return self.contentInset.right;
|
||||
}
|
||||
- (void)setJh_contentInsetRight:(CGFloat)jh_contentInsetRight
|
||||
{
|
||||
UIEdgeInsets inset = self.contentInset;
|
||||
inset.right = jh_contentInsetRight;
|
||||
self.contentInset = inset;
|
||||
}
|
||||
|
||||
#pragma mark - contentSize
|
||||
- (CGFloat)jh_contentSizeWidth
|
||||
{
|
||||
return self.contentSize.width;
|
||||
}
|
||||
- (void)setJh_contentSizeWidth:(CGFloat)jh_contentSizeWidth
|
||||
{
|
||||
CGSize size = self.contentSize;
|
||||
size.width = jh_contentSizeWidth;
|
||||
self.contentSize = size;
|
||||
}
|
||||
- (CGFloat)jh_contentSizeHeight
|
||||
{
|
||||
return self.contentSize.height;
|
||||
}
|
||||
- (void)setJh_contentSizeHeight:(CGFloat)jh_contentSizeHeight
|
||||
{
|
||||
CGSize size = self.contentSize;
|
||||
size.height = jh_contentSizeHeight;
|
||||
self.contentSize = size;
|
||||
}
|
||||
@end
|
||||
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// UIScrollView+JHRefresh.h
|
||||
// JHRefresh
|
||||
//
|
||||
// Created by Jiahai on 14-9-15.
|
||||
// Copyright (c) 2014年 Jiahai. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "JHRefreshConfig.h"
|
||||
|
||||
@interface UIScrollView (JHRefresh)
|
||||
|
||||
/**
|
||||
* 添加下拉刷新HeaderView
|
||||
*
|
||||
* @param aniViewClass 需要执行的动画的Class
|
||||
* @param beginRefresh 开始刷新时需要执行的操作,如网络请求等
|
||||
*/
|
||||
- (void)addRefreshHeaderViewWithAniViewClass:(Class)aniViewClass beginRefresh:(void (^)())beginRefresh;
|
||||
/**
|
||||
* 添加上拉加载FooterView
|
||||
*
|
||||
* @param aniViewClass 需要执行的动画的Class
|
||||
* @param beginRefresh 开始刷新时需要执行的操作,如网络请求等
|
||||
*/
|
||||
- (void)addRefreshFooterViewWithAniViewClass:(Class)aniViewClass beginRefresh:(void (^)())beginRefresh;
|
||||
|
||||
/**
|
||||
* 自动开启下拉刷新
|
||||
*/
|
||||
- (void)headerStartRefresh;
|
||||
|
||||
/**
|
||||
* 结束下拉刷新
|
||||
*
|
||||
* @param result 刷新结果
|
||||
*/
|
||||
- (void)headerEndRefreshingWithResult:(JHRefreshResult)result;
|
||||
/**
|
||||
* 结束上拉加载
|
||||
*/
|
||||
- (void)footerEndRefreshing;
|
||||
@end
|
||||
@@ -0,0 +1,95 @@
|
||||
//
|
||||
// UIScrollView+JHRefresh.m
|
||||
// JHRefresh
|
||||
//
|
||||
// Created by Jiahai on 14-9-15.
|
||||
// Copyright (c) 2014年 Jiahai. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UIScrollView+JHRefresh.h"
|
||||
#import "JHRefreshHeaderView.h"
|
||||
#import "JHRefreshFooterView.h"
|
||||
#import "AnimationView/JHRefreshCommonAniView.h"
|
||||
#import "AnimationView/JHRefreshAmazingAniView.h"
|
||||
#import "objc/runtime.h"
|
||||
|
||||
@interface UIScrollView()
|
||||
@property (nonatomic, weak) JHRefreshHeaderView *header;
|
||||
@property (nonatomic, weak) JHRefreshFooterView *footer;
|
||||
@end
|
||||
|
||||
@implementation UIScrollView (JHRefresh)
|
||||
|
||||
#pragma mark - 关联属性
|
||||
static char JHRefreshHeaderViewKey;
|
||||
static char JHRefreshFooterViewKey;
|
||||
|
||||
- (void)setHeader:(JHRefreshHeaderView *)header {
|
||||
[self willChangeValueForKey:@"JHRefreshHeaderViewKey"];
|
||||
objc_setAssociatedObject(self, &JHRefreshHeaderViewKey,
|
||||
header,
|
||||
OBJC_ASSOCIATION_ASSIGN);
|
||||
[self didChangeValueForKey:@"JHRefreshHeaderViewKey"];
|
||||
}
|
||||
|
||||
- (JHRefreshHeaderView *)header {
|
||||
return objc_getAssociatedObject(self, &JHRefreshHeaderViewKey);
|
||||
}
|
||||
|
||||
- (void)setFooter:(JHRefreshFooterView *)footer {
|
||||
[self willChangeValueForKey:@"JHRefreshFooterViewKey"];
|
||||
objc_setAssociatedObject(self, &JHRefreshFooterViewKey,
|
||||
footer,
|
||||
OBJC_ASSOCIATION_ASSIGN);
|
||||
[self didChangeValueForKey:@"JHRefreshFooterViewKey"];
|
||||
}
|
||||
|
||||
- (JHRefreshFooterView *)footer {
|
||||
return objc_getAssociatedObject(self, &JHRefreshFooterViewKey);
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
- (void)addRefreshHeaderViewWithAniViewClass:(Class)aniViewClass beginRefresh:(void (^)())beginRefresh
|
||||
{
|
||||
assert([aniViewClass isSubclassOfClass:[JHRefreshAniBaseView class]]);
|
||||
|
||||
if(!self.header)
|
||||
{
|
||||
JHRefreshHeaderView *headerView = [JHRefreshHeaderView createView];
|
||||
headerView.beginRefreshingBlock = beginRefresh;
|
||||
[self addSubview:headerView];
|
||||
self.header = headerView;
|
||||
headerView.aniView = [[aniViewClass alloc] init];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)addRefreshFooterViewWithAniViewClass:(Class)aniViewClass beginRefresh:(void (^)())beginRefresh
|
||||
{
|
||||
assert([aniViewClass isSubclassOfClass:[JHRefreshAniBaseView class]]);
|
||||
|
||||
if(!self.footer)
|
||||
{
|
||||
JHRefreshFooterView *footerView = [JHRefreshFooterView createView];
|
||||
footerView.beginRefreshingBlock = beginRefresh;
|
||||
[self addSubview:footerView];
|
||||
self.footer = footerView;
|
||||
footerView.aniView = [[aniViewClass alloc] init];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)headerStartRefresh
|
||||
{
|
||||
self.header.state = JHRefreshStatePulling;
|
||||
self.contentOffset = CGPointMake(self.contentOffset.x, -JHRefreshViewHeight);
|
||||
}
|
||||
|
||||
- (void)headerEndRefreshingWithResult:(JHRefreshResult)result
|
||||
{
|
||||
[self.header endRefreshingWithResult:result];
|
||||
}
|
||||
|
||||
- (void)footerEndRefreshing
|
||||
{
|
||||
[self.footer endRefreshingWithResult:JHRefreshResultNone];
|
||||
}
|
||||
@end
|
||||
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// UIView+JHExtension.h
|
||||
// JHRefresh
|
||||
//
|
||||
// Created by Jiahai on 14-9-15.
|
||||
// Copyright (c) 2014年 Jiahai. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface UIView (JHExtension)
|
||||
@property (nonatomic, assign) CGFloat jh_originX;
|
||||
@property (nonatomic, assign) CGFloat jh_originY;
|
||||
|
||||
@property (nonatomic, assign) CGFloat jh_width;
|
||||
@property (nonatomic, assign) CGFloat jh_height;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,56 @@
|
||||
//
|
||||
// UIView+JHExtension.m
|
||||
// JHRefresh
|
||||
//
|
||||
// Created by Jiahai on 14-9-15.
|
||||
// Copyright (c) 2014年 Jiahai. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UIView+JHExtension.h"
|
||||
|
||||
@implementation UIView (JHExtension)
|
||||
- (CGFloat)jh_originX
|
||||
{
|
||||
return self.frame.origin.x;
|
||||
}
|
||||
- (void)setJh_originX:(CGFloat)jh_originX
|
||||
{
|
||||
CGRect rect = self.frame;
|
||||
rect.origin.x = jh_originX;
|
||||
self.frame = rect;
|
||||
}
|
||||
|
||||
- (CGFloat)jh_originY
|
||||
{
|
||||
return self.frame.origin.y;
|
||||
}
|
||||
- (void)setJh_originY:(CGFloat)jh_originY
|
||||
{
|
||||
CGRect rect = self.frame;
|
||||
rect.origin.y = jh_originY;
|
||||
self.frame = rect;
|
||||
}
|
||||
|
||||
- (CGFloat)jh_width
|
||||
{
|
||||
return self.frame.size.width;
|
||||
}
|
||||
- (void)setJh_width:(CGFloat)jh_width
|
||||
{
|
||||
CGRect rect = self.frame;
|
||||
rect.size.width = jh_width;
|
||||
self.frame = rect;
|
||||
}
|
||||
|
||||
- (CGFloat)jh_height
|
||||
{
|
||||
return self.frame.size.height;
|
||||
}
|
||||
- (void)setJh_height:(CGFloat)jh_height
|
||||
{
|
||||
CGRect rect = self.frame;
|
||||
rect.size.height = jh_height;
|
||||
self.frame = rect;
|
||||
}
|
||||
|
||||
@end
|
||||