#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
]))
{
//设置UIView为的缩放模式
self
.
autoresizingMask
=
UIViewAutoresizingFlexibleWidth
;
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
.
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
.
contentsGravity
=
kCAGravityResizeAspect
;
//图像显示模式
layer
.
contents
=
(
id
)[
UIImage
imageNamed
:
arrow
].
CGImage
;
#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
;
}
-
(
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
:
)])
{
//通过委托egoRefreshTableHeaderDataSourceLastUpdated:返回时间,并格式化时间
NSDate
*
date
=
[
_delegate
egoRefreshTableHeaderDataSourceLastUpdated
:
self
];
[
NSDateFormatter
setDefaultFormatterBehavior
:
NSDateFormatterBehaviorDefault
];
NSDateFormatter
*
dateFormatter
=
[[[
NSDateFormatter
alloc
]
init
]
autorelease
];
// [dateFormatter setDateStyle:NSDateFormatterShortStyle];
// [dateFormatter setTimeStyle:NSDateFormatterShortStyle];
[
dateFormatter
setDateFormat
:
@"yyyy-MM-dd HH:mm:ss"
];
//更新最后显示的时间
NSString
*
lastUpdated
=
NSLocalizedString
(
@"last updated"
,
@""
);
_lastUpdatedLabel
.
text
=
[
NSString
stringWithFormat
:
@"%@ %@"
,
lastUpdated
,
[
dateFormatter
stringFromDate
:
date
]];
//保存最后刷新的时间,以便下次打开应用的时候还有
[[
NSUserDefaults
standardUserDefaults
]
setObject
:
_lastUpdatedLabel
.
text
forKey
:
@"EGORefreshTableView_LastRefresh"
];
[[
NSUserDefaults
standardUserDefaults
]
synchronize
];
}
else
{
_lastUpdatedLabel
.
text
=
nil
;
}
}
//设置下拉状态
-
(
void
)
setState:
(
EGOPullRefreshState
)
aState
{
switch
(
aState
)
{
case
EGOOPullRefreshPulling:
//如果是下拉状态,则更新_statusLabel内容,并把下拉图标旋转180度
// _statusLabel.text = NSLocalizedString(@"Release to refresh...", @"Release to refresh status");
_statusLabel
.
text
=
NSLocalizedString
(
@"release to refresh"
,
@""
);
[
CATransaction
begin
];
[
CATransaction
setAnimationDuration
:
FLIP_ANIMATION_DURATION
];
_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
;
//把transform设为默认值
[
CATransaction
commit
];
}
// _statusLabel.text = NSLocalizedString(@"Pull down to refresh...", @"Pull down to refresh status");
_statusLabel
.
text
=
NSLocalizedString
(
@"pull down to refresh"
,
@""
);
[
_activityView
stopAnimating
];
[
CATransaction
begin
];
[
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
=
NSLocalizedString
(
@"loading"
,
@""
);
[
_activityView
startAnimating
];
[
CATransaction
begin
];
[
CATransaction
setValue
:
(
id
)
kCFBooleanTrue
forKey
:
kCATransactionDisableActions
];
_arrowImage
.
hidden
=
YES
;
[
CATransaction
commit
];
break
;
default:
break
;
}
_state
=
aState
;
}
#pragma mark -
#pragma mark ScrollView Methods
//UIScrollView 滑动时调用该方法
-
(
void
)
egoRefreshScrollViewDidScroll:
(
UIScrollView
*
)
scrollView
{
if
(
_state
==
EGOOPullRefreshLoading
)
{
//如果正在载入中,则判断如果是上拉则不改变scrollView,如果是下拉,则保持HeaderView在顶部
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
)
{
//scrollView停止拖拽时计算下拉状态
BOOL
_loading
=
NO
;
//委托egoRefreshTableHeaderDataSourceIsLoading:返回用户载入数据的情况
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
];
}
//如果当前为默认状态,下拉大于65,并且不是在载入数据状态,则设置为Pull状态
else
if
(
_state
==
EGOOPullRefreshNormal
&&
scrollView
.
contentOffset
.
y
<
-
65.0f
&&
!
_loading
)
{
[
self
setState
:
EGOOPullRefreshPulling
];
}
if
(
scrollView
.
contentInset
.
top
!=
0
)
{
scrollView
.
contentInset
=
UIEdgeInsetsZero
;
}
}
}
//UIScrollView 停止拖拽时调用该方法
-
(
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
setContentInset
:
UIEdgeInsetsMake
(
0.0f
,
0.0f
,
0.0f
,
0.0f
)];
[
UIView
commitAnimations
];
[
self
setState
:
EGOOPullRefreshNormal
];
}
#pragma mark -
#pragma mark Dealloc
-
(
void
)
dealloc
{
_delegate
=
nil
;
_activityView
=
nil
;
_statusLabel
=
nil
;
_arrowImage
=
nil
;
_lastUpdatedLabel
=
nil
;
[
super
dealloc
];
}
@end