开源中国iOS客户端学习——(二)下拉刷新特效EGOTableViewPullRefresh

 打开开源中国iOS客户端应用程序第一步就是加载数据,经常我们在第二次以后打开的时候,我们界面显示的是上一次更新的数据,此时我们想看最新内容就需要去刷新数据加载这些内容,加载需要一个等待过程,如何能让用户在等待过程中不焦急,能够等待这个过程完成,这就需要给用户一个心里安慰,让用户知道该软件正在很努力很努力的执行自己命令,这就需要我们为自己应用程序添加一些特效;


      开源中国iOS客户端用到了不少特效,这些特效在当前很多应用软件中都比较流行,基本上这些特效都属于第三方类库,本次想说的是下拉刷新特效,EGOTableViewPullRefresh最开始是在Twitter中使用,最后做了开源,然后很多应用添加这个特效,常作为加载数据时将等待时间作为一个动画来过渡;

下拉刷新类库EGOTableViewPullRefresh资源文件下载地址:

 https://github.com/enormego/EGOTableViewPullRefresh/tree/


先这个特效的效果图

   


EGOTableViewPullRefresh资源文件中有两个文件,.m和.h文件,还有资源图片,就是下拉刷新箭头


资源图片一共4种色,可以根据喜好选用不同色的箭头,只需在EGORefreshTableHeaderView.m文件中修改一下。按照大小尺寸又可分两种,较大尺寸是用于iPad上使用的。



针对这些第三方类库,我们没必要去深入研究它们内部实现机制原理,只要知道怎么用就可以。不过,看一看别人实现原理,学学别人的方法还是很不错的,了解下人家牛人程序是怎么写的;


EGORefreshTableHeaderView.h

  1. #import <UIKit/UIKit.h>   
  2. #import <QuartzCore/QuartzCore.h>   
  3.   
  4. typedef enum{  
  5.     EGOOPullRefreshPulling = 0,  
  6.     EGOOPullRefreshNormal,  
  7.     EGOOPullRefreshLoading,   
  8. } EGOPullRefreshState;  
  9.   
  10. @protocol EGORefreshTableHeaderDelegate;  
  11. @interface EGORefreshTableHeaderView : UIView {  
  12.       
  13.     id _delegate;  
  14.     EGOPullRefreshState _state;  
  15.   
  16.     UILabel *_lastUpdatedLabel;  
  17.     UILabel *_statusLabel;  
  18.     CALayer *_arrowImage;  
  19.     UIActivityIndicatorView *_activityView;  
  20.       
  21. }  
  22.   
  23. @property(nonatomic,assign) id <EGORefreshTableHeaderDelegate> delegate;  
  24.   
  25. - (id)initWithFrame:(CGRect)frame arrowImageName:(NSString *)arrow textColor:(UIColor *)textColor;  
  26.   
  27. - (void)refreshLastUpdatedDate;  
  28. - (void)egoRefreshScrollViewDidScroll:(UIScrollView *)scrollView;  
  29. - (void)egoRefreshScrollViewDidEndDragging:(UIScrollView *)scrollView;  
  30. - (void)egoRefreshScrollViewDataSourceDidFinishedLoading:(UIScrollView *)scrollView;  
  31.   
  32. @end  
  33. //定义协议方法   
  34. @protocol EGORefreshTableHeaderDelegate  
  35. //下拉的时候调用此方法   
  36. - (void)egoRefreshTableHeaderDidTriggerRefresh:(EGORefreshTableHeaderView*)view;  
  37. //判断刷新状态情况,正在刷新或者是没刷新   
  38. - (BOOL)egoRefreshTableHeaderDataSourceIsLoading:(EGORefreshTableHeaderView*)view;  
  39. @optional  
  40. //返回刷新时间,回调方法   
  41. - (NSDate*)egoRefreshTableHeaderDataSourceLastUpdated:(EGORefreshTableHeaderView*)view;  
  42. @end  
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>

typedef enum{
	EGOOPullRefreshPulling = 0,
	EGOOPullRefreshNormal,
	EGOOPullRefreshLoading,	
} EGOPullRefreshState;

@protocol EGORefreshTableHeaderDelegate;
@interface EGORefreshTableHeaderView : UIView {
	
	id _delegate;
	EGOPullRefreshState _state;

	UILabel *_lastUpdatedLabel;
	UILabel *_statusLabel;
	CALayer *_arrowImage;
	UIActivityIndicatorView *_activityView;
	
}

@property(nonatomic,assign) id <EGORefreshTableHeaderDelegate> delegate;

- (id)initWithFrame:(CGRect)frame arrowImageName:(NSString *)arrow textColor:(UIColor *)textColor;

- (void)refreshLastUpdatedDate;
- (void)egoRefreshScrollViewDidScroll:(UIScrollView *)scrollView;
- (void)egoRefreshScrollViewDidEndDragging:(UIScrollView *)scrollView;
- (void)egoRefreshScrollViewDataSourceDidFinishedLoading:(UIScrollView *)scrollView;

@end
//定义协议方法
@protocol EGORefreshTableHeaderDelegate
//下拉的时候调用此方法
- (void)egoRefreshTableHeaderDidTriggerRefresh:(EGORefreshTableHeaderView*)view;
//判断刷新状态情况,正在刷新或者是没刷新
- (BOOL)egoRefreshTableHeaderDataSourceIsLoading:(EGORefreshTableHeaderView*)view;
@optional
//返回刷新时间,回调方法
- (NSDate*)egoRefreshTableHeaderDataSourceLastUpdated:(EGORefreshTableHeaderView*)view;
@end

首先是定义了一个枚举类型EGOPullRefreshState表示当前我们操作在哪种状态下,有下拉状态、正常状态、数据加载状态;


@protocol EGORefreshTableHeaderDelegate;表示声明有这个协议,该协议里面声明了一些方法,只要其他的类遵循了这个协议(也就是遵循了它的规定),就可以去实现协议里面方法,协议里的方法是留给遵循这个协议的类去实现的,也是留给外部实现接口;


EGORefreshTableHeaderView成员变量定义两个label用于提示下拉过程所处状态,和显示的刷新时间。定义的CALayer类对象装载显示图片。UIActivityIndicatorView类对象显示一个等待动画;


@property(nonatomic,assign)id <EGORefreshTableHeaderDelegate> delegate;声明一个协议对象;


接着下面的是EGORefreshTableHeaderView类成员函数,用于实现类库中下拉刷新的效果;


最后定义了4个协议方法,其中最后一个协议方法为可选实现;


下面是EGORefreshTableHeaderView.m文件,想说的都在注释里


  1. #import "EGORefreshTableHeaderView.h"   
  2.   
  3.   
  4. #define TEXT_COLOR   [UIColor colorWithRed:87.0/255.0 green:108.0/255.0 blue:137.0/255.0 alpha:1.0]   
  5. #define FLIP_ANIMATION_DURATION 0.18f   
  6.   
  7.   
  8. //设置的一个私有接口,只能本类来使用   
  9. @interface EGORefreshTableHeaderView (Private)  
  10. - (void)setState:(EGOPullRefreshState)aState;  
  11. @end  
  12.   
  13. @implementation EGORefreshTableHeaderView  
  14.   
  15. @synthesize delegate=_delegate;  
  16.   
  17. //初始化框架属性,   
  18. - (id)initWithFrame:(CGRect)frame arrowImageName:(NSString *)arrow textColor:(UIColor *)textColor  {  
  19.     if((self = [super initWithFrame:frame])) {  
  20. //      self.view自动适应bounds的宽度   
  21.         self.autoresizingMask = UIViewAutoresizingFlexibleWidth;  
  22. //        self.view背景色和透明度设置   
  23.         self.backgroundColor = [UIColor colorWithRed:226.0/255.0 green:231.0/255.0 blue:237.0/255.0 alpha:1.0];  
  24.   
  25.         UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, frame.size.height - 30.0f, self.frame.size.width, 20.0f)];  
  26.         label.autoresizingMask = UIViewAutoresizingFlexibleWidth;  
  27.         label.font = [UIFont systemFontOfSize:12.0f];  
  28.         label.textColor = textColor;  
  29. //        label文本阴影颜色   
  30.         label.shadowColor = [UIColor colorWithWhite:0.9f alpha:1.0f];  
  31.         label.shadowOffset = CGSizeMake(0.0f, 1.0f);  
  32.         label.backgroundColor = [UIColor clearColor];  
  33.         label.textAlignment = UITextAlignmentCenter;  
  34.         [self addSubview:label];  
  35.         _lastUpdatedLabel=label;  
  36.         [label release];  
  37.           
  38.         label = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, frame.size.height - 48.0f, self.frame.size.width, 20.0f)];  
  39.         label.autoresizingMask = UIViewAutoresizingFlexibleWidth;  
  40.         label.font = [UIFont boldSystemFontOfSize:13.0f];  
  41.         label.textColor = textColor;  
  42.         label.shadowColor = [UIColor colorWithWhite:0.9f alpha:1.0f];  
  43.         label.shadowOffset = CGSizeMake(0.0f, 1.0f);  
  44.         label.backgroundColor = [UIColor clearColor];  
  45.         label.textAlignment = UITextAlignmentCenter;  
  46.         [self addSubview:label];  
  47.         _statusLabel=label;  
  48.         [label release];  
  49.           
  50.         CALayer *layer = [CALayer layer];  
  51.         layer.frame = CGRectMake(25.0f, frame.size.height - 65.0f, 30.0f, 55.0f);  
  52. //        设置layer在view上以某种形式适应   
  53.         layer.contentsGravity = kCAGravityResizeAspect;  
  54.         layer.contents = (id)[UIImage imageNamed:arrow].CGImage;  
  55.           
  56. //        判断设备版本,因为一些iOS特性是在最后新增的,要求设备配置高一些,所以做一下判断   
  57. #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000   
  58.         if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {  
  59.             layer.contentsScale = [[UIScreen mainScreen] scale];  
  60.         }  
  61. #endif   
  62.           
  63.         [[self layer] addSublayer:layer];  
  64.         _arrowImage=layer;  
  65.           
  66.         UIActivityIndicatorView *view = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];  
  67.         view.frame = CGRectMake(25.0f, frame.size.height - 38.0f, 20.0f, 20.0f);  
  68.         [self addSubview:view];  
  69.         _activityView = view;  
  70.         [view release];  
  71.           
  72.           
  73.         [self setState:EGOOPullRefreshNormal];  
  74.           
  75.     }  
  76.       
  77.     return self;  
  78.       
  79. }  
#import "EGORefreshTableHeaderView.h"


#define TEXT_COLOR	 [UIColor colorWithRed:87.0/255.0 green:108.0/255.0 blue:137.0/255.0 alpha:1.0]
#define FLIP_ANIMATION_DURATION 0.18f


//设置的一个私有接口,只能本类来使用
@interface EGORefreshTableHeaderView (Private)
- (void)setState:(EGOPullRefreshState)aState;
@end

@implementation EGORefreshTableHeaderView

@synthesize delegate=_delegate;

//初始化框架属性,
- (id)initWithFrame:(CGRect)frame arrowImageName:(NSString *)arrow textColor:(UIColor *)textColor  {
    if((self = [super initWithFrame:frame])) {
//		self.view自动适应bounds的宽度
		self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
//        self.view背景色和透明度设置
		self.backgroundColor = [UIColor colorWithRed:226.0/255.0 green:231.0/255.0 blue:237.0/255.0 alpha:1.0];

		UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, frame.size.height - 30.0f, self.frame.size.width, 20.0f)];
		label.autoresizingMask = UIViewAutoresizingFlexibleWidth;
		label.font = [UIFont systemFontOfSize:12.0f];
		label.textColor = textColor;
//        label文本阴影颜色
		label.shadowColor = [UIColor colorWithWhite:0.9f alpha:1.0f];
		label.shadowOffset = CGSizeMake(0.0f, 1.0f);
		label.backgroundColor = [UIColor clearColor];
		label.textAlignment = UITextAlignmentCenter;
		[self addSubview:label];
		_lastUpdatedLabel=label;
		[label release];
		
		label = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, frame.size.height - 48.0f, self.frame.size.width, 20.0f)];
		label.autoresizingMask = UIViewAutoresizingFlexibleWidth;
		label.font = [UIFont boldSystemFontOfSize:13.0f];
		label.textColor = textColor;
		label.shadowColor = [UIColor colorWithWhite:0.9f alpha:1.0f];
		label.shadowOffset = CGSizeMake(0.0f, 1.0f);
		label.backgroundColor = [UIColor clearColor];
		label.textAlignment = UITextAlignmentCenter;
		[self addSubview:label];
		_statusLabel=label;
		[label release];
		
		CALayer *layer = [CALayer layer];
		layer.frame = CGRectMake(25.0f, frame.size.height - 65.0f, 30.0f, 55.0f);
//        设置layer在view上以某种形式适应
		layer.contentsGravity = kCAGravityResizeAspect;
		layer.contents = (id)[UIImage imageNamed:arrow].CGImage;
		
//        判断设备版本,因为一些iOS特性是在最后新增的,要求设备配置高一些,所以做一下判断
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000
		if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
			layer.contentsScale = [[UIScreen mainScreen] scale];
		}
#endif
		
		[[self layer] addSublayer:layer];
		_arrowImage=layer;
		
		UIActivityIndicatorView *view = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
		view.frame = CGRectMake(25.0f, frame.size.height - 38.0f, 20.0f, 20.0f);
		[self addSubview:view];
		_activityView = view;
		[view release];
		
		
		[self setState:EGOOPullRefreshNormal];
		
    }
	
    return self;
	
}

  1. //初始化当前视图的frame   
  2. - (id)initWithFrame:(CGRect)frame  {  
  3.   return [self initWithFrame:frame arrowImageName:@"blueArrow.png" textColor:TEXT_COLOR];  
  4. }  
  5.   
  6. #pragma mark -   
  7. #pragma mark Setters   
  8.   
  9. //获取最后一次更新的时间   
  10. - (void)refreshLastUpdatedDate {  
  11.       
  12.     if ([_delegate respondsToSelector:@selector(egoRefreshTableHeaderDataSourceLastUpdated:)]) {  
  13.           
  14.         NSDate *date = [_delegate egoRefreshTableHeaderDataSourceLastUpdated:self];  
  15. //      NSDateFormatter实例创建字符串,来表示NSDate和NSCalendarDate对象,已预订格式化字符串输出     
  16.         [NSDateFormatter setDefaultFormatterBehavior:NSDateFormatterBehaviorDefault];  
  17.         NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];  
  18. //        设置日期输出格式   
  19.         [dateFormatter setDateStyle:NSDateFormatterShortStyle];  
  20. //        设置时间显示格式   
  21.         [dateFormatter setTimeStyle:NSDateFormatterShortStyle];  
  22.   
  23. //      _lastUpdatedLabel.text = [NSString stringWithFormat:@"Last Updated: %@", [dateFormatter stringFromDate:date]];   
  24.         _lastUpdatedLabel.text = [NSString stringWithFormat:@"最后更新: %@", [dateFormatter stringFromDate:date]];  
  25. //        存储_lastUpdatedLabel.text内容,放到字典中   
  26.         [[NSUserDefaults standardUserDefaults] setObject:_lastUpdatedLabel.text forKey:@"EGORefreshTableView_LastRefresh"];  
  27. //        将NSUserDefaults存储数据放到磁盘   
  28.         [[NSUserDefaults standardUserDefaults] synchronize];  
  29.           
  30.     } else {  
  31.           
  32.         _lastUpdatedLabel.text = nil;  
  33.           
  34.     }  
  35.   
  36. }  
//初始化当前视图的frame
- (id)initWithFrame:(CGRect)frame  {
  return [self initWithFrame:frame arrowImageName:@"blueArrow.png" textColor:TEXT_COLOR];
}

#pragma mark -
#pragma mark Setters

//获取最后一次更新的时间
- (void)refreshLastUpdatedDate {
	
	if ([_delegate respondsToSelector:@selector(egoRefreshTableHeaderDataSourceLastUpdated:)]) {
		
		NSDate *date = [_delegate egoRefreshTableHeaderDataSourceLastUpdated:self];
//		NSDateFormatter实例创建字符串,来表示NSDate和NSCalendarDate对象,已预订格式化字符串输出  
		[NSDateFormatter setDefaultFormatterBehavior:NSDateFormatterBehaviorDefault];
		NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
//        设置日期输出格式
		[dateFormatter setDateStyle:NSDateFormatterShortStyle];
//        设置时间显示格式
		[dateFormatter setTimeStyle:NSDateFormatterShortStyle];

//		_lastUpdatedLabel.text = [NSString stringWithFormat:@"Last Updated: %@", [dateFormatter stringFromDate:date]];
        _lastUpdatedLabel.text = [NSString stringWithFormat:@"最后更新: %@", [dateFormatter stringFromDate:date]];
//        存储_lastUpdatedLabel.text内容,放到字典中
		[[NSUserDefaults standardUserDefaults] setObject:_lastUpdatedLabel.text forKey:@"EGORefreshTableView_LastRefresh"];
//        将NSUserDefaults存储数据放到磁盘
		[[NSUserDefaults standardUserDefaults] synchronize];
		
	} else {
		
		_lastUpdatedLabel.text = nil;
		
	}

}

  1. - (void)setState:(EGOPullRefreshState)aState{  
  2.       
  3.     switch (aState) {  
  4.             /*触摸屏幕下拉状态*/  
  5.         case EGOOPullRefreshPulling:  
  6.               
  7. //          _statusLabel.text = NSLocalizedString(@"Release to refresh...", @"Release to refresh status");   
  8.             _statusLabel.text = @"松开即可刷新";  
  9. //            设置下拉刷新过程,箭头的图片的一个动画过程   
  10.             [CATransaction begin];  
  11. //            动画时间   
  12.             [CATransaction setAnimationDuration:FLIP_ANIMATION_DURATION];  
  13. //            下拉刷新箭头一个翻转过程,(M_PI / 180.0)是角度转换为弧度   
  14.               
  15.             _arrowImage.transform = CATransform3DMakeRotation((M_PI / 180.0) * 180.0f, 0.0f, 0.0f, 1.0f);  
  16. //            动画结束   
  17.             [CATransaction commit];  
  18.               
  19.             break;  
  20.             /*刚开始触摸屏幕准备下拉的时候的状态*/  
  21.         case EGOOPullRefreshNormal:  
  22.               
  23.             if (_state == EGOOPullRefreshPulling) {  
  24.                 [CATransaction begin];  
  25.                 [CATransaction setAnimationDuration:FLIP_ANIMATION_DURATION];  
  26.                 _arrowImage.transform = CATransform3DIdentity;  
  27.                 [CATransaction commit];  
  28.             }  
  29.               
  30. //          _statusLabel.text = NSLocalizedString(@"Pull down to refresh...", @"Pull down to refresh status");   
  31.             _statusLabel.text = @"下拉可以刷新";  
  32.             [_activityView stopAnimating];  
  33.             [CATransaction begin];  
  34. //            因为下拉刷新完成好就不需要下拉动画,此时_activityView动画显示   
  35. //            显示事物关闭动画效果 kCFBooleanTrue关闭 kCFBooleanFalse开启   
  36.             [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];   
  37.             _arrowImage.hidden = NO;  
  38.             _arrowImage.transform = CATransform3DIdentity;  
  39.             [CATransaction commit];  
  40. //          更新下时间   
  41.             [self refreshLastUpdatedDate];  
  42.               
  43.             break;  
  44.             /*触摸手指松开,完成下拉操作的状态*/  
  45.         case EGOOPullRefreshLoading:  
  46.               
  47. //          _statusLabel.text = NSLocalizedString(@"Loading...", @"Loading Status");   
  48.             _statusLabel.text = @"加载中";  
  49.             [_activityView startAnimating];  
  50.             [CATransaction begin];  
  51.             [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];   
  52.             _arrowImage.hidden = YES;  
  53.             [CATransaction commit];  
  54.               
  55.             break;  
  56.         default:  
  57.             break;  
  58.     }  
  59.       
  60.     _state = aState;  
  61. }  
- (void)setState:(EGOPullRefreshState)aState{
	
	switch (aState) {
            /*触摸屏幕下拉状态*/
		case EGOOPullRefreshPulling:
			
//			_statusLabel.text = NSLocalizedString(@"Release to refresh...", @"Release to refresh status");
            _statusLabel.text = @"松开即可刷新";
//            设置下拉刷新过程,箭头的图片的一个动画过程
			[CATransaction begin];
//            动画时间
			[CATransaction setAnimationDuration:FLIP_ANIMATION_DURATION];
//            下拉刷新箭头一个翻转过程,(M_PI / 180.0)是角度转换为弧度
			
            _arrowImage.transform = CATransform3DMakeRotation((M_PI / 180.0) * 180.0f, 0.0f, 0.0f, 1.0f);
//            动画结束
			[CATransaction commit];
			
			break;
            /*刚开始触摸屏幕准备下拉的时候的状态*/
		case EGOOPullRefreshNormal:
			
			if (_state == EGOOPullRefreshPulling) {
				[CATransaction begin];
				[CATransaction setAnimationDuration:FLIP_ANIMATION_DURATION];
				_arrowImage.transform = CATransform3DIdentity;
				[CATransaction commit];
			}
			
//			_statusLabel.text = NSLocalizedString(@"Pull down to refresh...", @"Pull down to refresh status");
            _statusLabel.text = @"下拉可以刷新";
			[_activityView stopAnimating];
			[CATransaction begin];
//            因为下拉刷新完成好就不需要下拉动画,此时_activityView动画显示
//            显示事物关闭动画效果 kCFBooleanTrue关闭 kCFBooleanFalse开启
			[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions]; 
			_arrowImage.hidden = NO;
			_arrowImage.transform = CATransform3DIdentity;
			[CATransaction commit];
//			更新下时间
			[self refreshLastUpdatedDate];
			
			break;
            /*触摸手指松开,完成下拉操作的状态*/
		case EGOOPullRefreshLoading:
			
//			_statusLabel.text = NSLocalizedString(@"Loading...", @"Loading Status");
            _statusLabel.text = @"加载中";
			[_activityView startAnimating];
			[CATransaction begin];
			[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions]; 
			_arrowImage.hidden = YES;
			[CATransaction commit];
			
			break;
		default:
			break;
	}
	
	_state = aState;
}


  1. #pragma mark -   
  2. #pragma mark ScrollView Methods   
  3.   
  4. - (void)egoRefreshScrollViewDidScroll:(UIScrollView *)scrollView {    
  5.       
  6.     if (_state == EGOOPullRefreshLoading) {  
  7.           
  8.         CGFloat offset = MAX(scrollView.contentOffset.y * -1, 0);  
  9.         offset = MIN(offset, 60);  
  10.         scrollView.contentInset = UIEdgeInsetsMake(offset, 0.0f, 0.0f, 0.0f);  
  11.           
  12.     } else if (scrollView.isDragging) {  
  13.           
  14.         BOOL _loading = NO;  
  15.         if ([_delegate respondsToSelector:@selector(egoRefreshTableHeaderDataSourceIsLoading:)]) {  
  16.             _loading = [_delegate egoRefreshTableHeaderDataSourceIsLoading:self];  
  17.         }  
  18.           
  19.         if (_state == EGOOPullRefreshPulling && scrollView.contentOffset.y > -65.0f && scrollView.contentOffset.y < 0.0f && !_loading) {  
  20.             [self setState:EGOOPullRefreshNormal];  
  21.         } else if (_state == EGOOPullRefreshNormal && scrollView.contentOffset.y < -65.0f && !_loading) {  
  22.             [self setState:EGOOPullRefreshPulling];  
  23.         }  
  24. //      设置下拉属性scrollView框架恢复初始位置   
  25.         if (scrollView.contentInset.top != 0) {  
  26. //        A UIEdgeInsets struct whose top, left, bottom, and right fields are all set to the value 0.   
  27.             scrollView.contentInset = UIEdgeInsetsZero;  
  28.         }  
  29.           
  30.     }  
  31.       
  32. }  
  33.   
  34. - (void)egoRefreshScrollViewDidEndDragging:(UIScrollView *)scrollView {  
  35.       
  36.     BOOL _loading = NO;  
  37.     if ([_delegate respondsToSelector:@selector(egoRefreshTableHeaderDataSourceIsLoading:)]) {  
  38.         _loading = [_delegate egoRefreshTableHeaderDataSourceIsLoading:self];  
  39.     }  
  40.       
  41.     if (scrollView.contentOffset.y <= - 65.0f && !_loading) {  
  42.           
  43.         if ([_delegate respondsToSelector:@selector(egoRefreshTableHeaderDidTriggerRefresh:)]) {  
  44.             [_delegate egoRefreshTableHeaderDidTriggerRefresh:self];  
  45.         }  
  46.           
  47.         [self setState:EGOOPullRefreshLoading];  
  48.         [UIView beginAnimations:nil context:NULL];  
  49.         [UIView setAnimationDuration:0.2];  
  50.         scrollView.contentInset = UIEdgeInsetsMake(60.0f, 0.0f, 0.0f, 0.0f);  
  51.         [UIView commitAnimations];  
  52.           
  53.     }  
  54.       
  55. }  
  56. //数据加载完成后调用此方法   
  57. - (void)egoRefreshScrollViewDataSourceDidFinishedLoading:(UIScrollView *)scrollView {     
  58.       
  59.     [UIView beginAnimations:nil context:NULL];  
  60.     [UIView setAnimationDuration:.3];  
  61. //    数据加载完成后,scrollView恢复位置大小   
  62.     [scrollView setContentInset:UIEdgeInsetsMake(0.0f, 0.0f, 0.0f, 0.0f)];  
  63.     [UIView commitAnimations];  
  64. //  数据加载完成,   
  65.     [self setState:EGOOPullRefreshNormal];  
  66.   
  67. }  
#pragma mark -
#pragma mark ScrollView Methods

- (void)egoRefreshScrollViewDidScroll:(UIScrollView *)scrollView {	
	
	if (_state == EGOOPullRefreshLoading) {
		
		CGFloat offset = MAX(scrollView.contentOffset.y * -1, 0);
		offset = MIN(offset, 60);
		scrollView.contentInset = UIEdgeInsetsMake(offset, 0.0f, 0.0f, 0.0f);
		
	} else if (scrollView.isDragging) {
		
		BOOL _loading = NO;
		if ([_delegate respondsToSelector:@selector(egoRefreshTableHeaderDataSourceIsLoading:)]) {
			_loading = [_delegate egoRefreshTableHeaderDataSourceIsLoading:self];
		}
		
		if (_state == EGOOPullRefreshPulling && scrollView.contentOffset.y > -65.0f && scrollView.contentOffset.y < 0.0f && !_loading) {
			[self setState:EGOOPullRefreshNormal];
		} else if (_state == EGOOPullRefreshNormal && scrollView.contentOffset.y < -65.0f && !_loading) {
			[self setState:EGOOPullRefreshPulling];
		}
//		设置下拉属性scrollView框架恢复初始位置
		if (scrollView.contentInset.top != 0) {
//        A UIEdgeInsets struct whose top, left, bottom, and right fields are all set to the value 0.
			scrollView.contentInset = UIEdgeInsetsZero;
		}
		
	}
	
}

- (void)egoRefreshScrollViewDidEndDragging:(UIScrollView *)scrollView {
	
	BOOL _loading = NO;
	if ([_delegate respondsToSelector:@selector(egoRefreshTableHeaderDataSourceIsLoading:)]) {
		_loading = [_delegate egoRefreshTableHeaderDataSourceIsLoading:self];
	}
	
	if (scrollView.contentOffset.y <= - 65.0f && !_loading) {
		
		if ([_delegate respondsToSelector:@selector(egoRefreshTableHeaderDidTriggerRefresh:)]) {
			[_delegate egoRefreshTableHeaderDidTriggerRefresh:self];
		}
		
		[self setState:EGOOPullRefreshLoading];
		[UIView beginAnimations:nil context:NULL];
		[UIView setAnimationDuration:0.2];
		scrollView.contentInset = UIEdgeInsetsMake(60.0f, 0.0f, 0.0f, 0.0f);
		[UIView commitAnimations];
		
	}
	
}
//数据加载完成后调用此方法
- (void)egoRefreshScrollViewDataSourceDidFinishedLoading:(UIScrollView *)scrollView {	
	
	[UIView beginAnimations:nil context:NULL];
	[UIView setAnimationDuration:.3];
//    数据加载完成后,scrollView恢复位置大小
	[scrollView setContentInset:UIEdgeInsetsMake(0.0f, 0.0f, 0.0f, 0.0f)];
	[UIView commitAnimations];
//	数据加载完成,
	[self setState:EGOOPullRefreshNormal];

}


  1. #pragma mark -   
  2. #pragma mark Dealloc   
  3.   
  4. - (void)dealloc {  
  5.       
  6.     _delegate=nil;  
  7.     _activityView = nil;  
  8.     _statusLabel = nil;  
  9.     _arrowImage = nil;  
  10.     _lastUpdatedLabel = nil;  
  11.     [super dealloc];  
  12. }  
  13.   
  14.   
  15. @end  
#pragma mark -
#pragma mark Dealloc

- (void)dealloc {
	
	_delegate=nil;
	_activityView = nil;
	_statusLabel = nil;
	_arrowImage = nil;
	_lastUpdatedLabel = nil;
    [super dealloc];
}


@end


当我们想使用这个下拉刷新类库的时候,在使用类里声明这个协议<EGORefreshTableHeaderDelegate>,把当前类self交付给下拉刷新库的协议对象,也就是xx.delegate=self;

怎样让其他类来使用这里面效果,这时我们就可以委托另一个类来实现协议的方法。

选中一个协议方法,右键选择Jump to Definition就可以看到哪些类被委托了,怎样使用了这个类的协议方法:




正在学习过程中,错误之处请指正,欢迎交流,共同学习;


欢迎转载分享,请注明出处 http://blog.csdn.net/duxinfeng2010


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值