mirror of
https://github.com/wu736139669/Ash_AWord.git
synced 2026-08-08 06:46:38 +00:00
add mjrefresh
This commit is contained in:
Generated
Executable
BIN
Binary file not shown.
|
After Width: | Height: | Size: 3.0 KiB |
@@ -0,0 +1,9 @@
|
||||
// 代码地址: https://github.com/CoderMJLee/MJRefresh
|
||||
// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000
|
||||
|
||||
#import "UIScrollView+MJRefresh.h"
|
||||
#import "MJRefreshGifHeader.h"
|
||||
#import "MJRefreshLegendHeader.h"
|
||||
#import "MJRefreshGifFooter.h"
|
||||
#import "MJRefreshLegendFooter.h"
|
||||
#import "MJRefreshConst.h"
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
// 代码地址: https://github.com/CoderMJLee/MJRefresh
|
||||
// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000
|
||||
// MJRefreshComponent.h
|
||||
// MJRefreshExample
|
||||
//
|
||||
// Created by MJ Lee on 15/3/4.
|
||||
// Copyright (c) 2015年 itcast. All rights reserved.
|
||||
// 刷新组件:基本的开始刷新和结束刷新行为
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface MJRefreshComponent : UIView
|
||||
{
|
||||
UIEdgeInsets _scrollViewOriginalInset;
|
||||
__weak UIScrollView *_scrollView;
|
||||
}
|
||||
|
||||
#pragma mark - 文字处理
|
||||
/** 文字颜色 */
|
||||
@property (strong, nonatomic) UIColor *textColor;
|
||||
/** 字体大小 */
|
||||
@property (strong, nonatomic) UIFont *font;
|
||||
|
||||
#pragma mark - 刷新处理
|
||||
/** 正在刷新的回调 */
|
||||
@property (copy, nonatomic) void (^refreshingBlock)();
|
||||
/** 设置回调对象和回调方法 */
|
||||
- (void)setRefreshingTarget:(id)target refreshingAction:(SEL)action;
|
||||
@property (weak, nonatomic) id refreshingTarget;
|
||||
@property (assign, nonatomic) SEL refreshingAction;
|
||||
/** 进入刷新状态 */
|
||||
- (void)beginRefreshing;
|
||||
/** 结束刷新状态 */
|
||||
- (void)endRefreshing;
|
||||
/** 是否正在刷新 */
|
||||
- (BOOL)isRefreshing;
|
||||
@end
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
// 代码地址: https://github.com/CoderMJLee/MJRefresh
|
||||
// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000
|
||||
// MJRefreshComponent.m
|
||||
// MJRefreshExample
|
||||
//
|
||||
// Created by MJ Lee on 15/3/4.
|
||||
// Copyright (c) 2015年 itcast. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MJRefreshComponent.h"
|
||||
#import "MJRefreshConst.h"
|
||||
#import "UIView+MJExtension.h"
|
||||
|
||||
@interface MJRefreshComponent()
|
||||
/** 记录scrollView刚开始的inset */
|
||||
@property (assign, nonatomic) UIEdgeInsets scrollViewOriginalInset;
|
||||
/** 父控件 */
|
||||
@property (weak, nonatomic) UIScrollView *scrollView;
|
||||
@end
|
||||
|
||||
@implementation MJRefreshComponent
|
||||
#pragma mark - 初始化
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
{
|
||||
if (self = [super initWithFrame:frame]) {
|
||||
// 基本属性
|
||||
self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
|
||||
self.backgroundColor = [UIColor clearColor];
|
||||
|
||||
// 默认文字颜色和字体大小
|
||||
self.textColor = MJRefreshLabelTextColor;
|
||||
self.font = MJRefreshLabelFont;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)willMoveToSuperview:(UIView *)newSuperview
|
||||
{
|
||||
[super willMoveToSuperview:newSuperview];
|
||||
|
||||
// 旧的父控件
|
||||
[self.superview removeObserver:self forKeyPath:MJRefreshContentOffset context:nil];
|
||||
|
||||
if (newSuperview) { // 新的父控件
|
||||
[newSuperview addObserver:self forKeyPath:MJRefreshContentOffset options:NSKeyValueObservingOptionNew context:nil];
|
||||
|
||||
// 设置宽度
|
||||
self.mj_w = newSuperview.mj_w;
|
||||
// 设置位置
|
||||
self.mj_x = 0;
|
||||
|
||||
// 记录UIScrollView
|
||||
self.scrollView = (UIScrollView *)newSuperview;
|
||||
// 设置永远支持垂直弹簧效果
|
||||
self.scrollView.alwaysBounceVertical = YES;
|
||||
// 记录UIScrollView最开始的contentInset
|
||||
self.scrollViewOriginalInset = self.scrollView.contentInset;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - 公共方法
|
||||
- (void)setRefreshingTarget:(id)target refreshingAction:(SEL)action
|
||||
{
|
||||
self.refreshingTarget = target;
|
||||
self.refreshingAction = action;
|
||||
}
|
||||
|
||||
- (void)beginRefreshing
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
- (void)endRefreshing
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
- (BOOL)isRefreshing {
|
||||
return NO;
|
||||
}
|
||||
@end
|
||||
@@ -0,0 +1,48 @@
|
||||
// 代码地址: https://github.com/CoderMJLee/MJRefresh
|
||||
// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
// 日志输出
|
||||
#ifdef DEBUG
|
||||
#define MJLog(...) NSLog(__VA_ARGS__)
|
||||
#else
|
||||
#define MJLog(...)
|
||||
#endif
|
||||
|
||||
// 过期提醒
|
||||
#define MJDeprecated(instead) NS_DEPRECATED(2_0, 2_0, 2_0, 2_0, instead)
|
||||
|
||||
// 运行时objc_msgSend
|
||||
#define msgSend(...) ((void (*)(void *, SEL, UIView *))objc_msgSend)(__VA_ARGS__)
|
||||
#define msgTarget(target) (__bridge void *)(target)
|
||||
|
||||
// RGB颜色
|
||||
#define MJColor(r, g, b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1.0]
|
||||
|
||||
// 文字颜色
|
||||
#define MJRefreshLabelTextColor MJColor(100, 100, 100)
|
||||
|
||||
// 字体大小
|
||||
#define MJRefreshLabelFont [UIFont boldSystemFontOfSize:13]
|
||||
|
||||
// 图片路径
|
||||
#define MJRefreshSrcName(file) [@"MJRefresh.bundle" stringByAppendingPathComponent:file]
|
||||
|
||||
// 常量
|
||||
UIKIT_EXTERN const CGFloat MJRefreshHeaderHeight;
|
||||
UIKIT_EXTERN const CGFloat MJRefreshFooterHeight;
|
||||
UIKIT_EXTERN const CGFloat MJRefreshFastAnimationDuration;
|
||||
UIKIT_EXTERN const CGFloat MJRefreshSlowAnimationDuration;
|
||||
|
||||
UIKIT_EXTERN NSString *const MJRefreshHeaderUpdatedTimeKey;
|
||||
UIKIT_EXTERN NSString *const MJRefreshContentOffset;
|
||||
UIKIT_EXTERN NSString *const MJRefreshContentSize;
|
||||
UIKIT_EXTERN NSString *const MJRefreshPanState;
|
||||
|
||||
UIKIT_EXTERN NSString *const MJRefreshHeaderStateIdleText;
|
||||
UIKIT_EXTERN NSString *const MJRefreshHeaderStatePullingText;
|
||||
UIKIT_EXTERN NSString *const MJRefreshHeaderStateRefreshingText;
|
||||
|
||||
UIKIT_EXTERN NSString *const MJRefreshFooterStateIdleText;
|
||||
UIKIT_EXTERN NSString *const MJRefreshFooterStateRefreshingText;
|
||||
UIKIT_EXTERN NSString *const MJRefreshFooterStateNoMoreDataText;
|
||||
@@ -0,0 +1,21 @@
|
||||
// 代码地址: https://github.com/CoderMJLee/MJRefresh
|
||||
// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
const CGFloat MJRefreshHeaderHeight = 64.0;
|
||||
const CGFloat MJRefreshFooterHeight = 44.0;
|
||||
const CGFloat MJRefreshFastAnimationDuration = 0.25;
|
||||
const CGFloat MJRefreshSlowAnimationDuration = 0.4;
|
||||
|
||||
NSString *const MJRefreshHeaderUpdatedTimeKey = @"MJRefreshHeaderUpdatedTimeKey";
|
||||
NSString *const MJRefreshContentOffset = @"contentOffset";
|
||||
NSString *const MJRefreshContentSize = @"contentSize";
|
||||
NSString *const MJRefreshPanState = @"pan.state";
|
||||
|
||||
NSString *const MJRefreshHeaderStateIdleText = @"下拉可以刷新";
|
||||
NSString *const MJRefreshHeaderStatePullingText = @"松开立即刷新";
|
||||
NSString *const MJRefreshHeaderStateRefreshingText = @"正在刷新数据中...";
|
||||
|
||||
NSString *const MJRefreshFooterStateIdleText = @"点击加载更多";
|
||||
NSString *const MJRefreshFooterStateRefreshingText = @"正在加载更多的数据...";
|
||||
NSString *const MJRefreshFooterStateNoMoreDataText = @"已经全部加载完毕";
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
// 代码地址: https://github.com/CoderMJLee/MJRefresh
|
||||
// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000
|
||||
// MJRefreshFooter.h
|
||||
// MJRefreshExample
|
||||
//
|
||||
// Created by MJ Lee on 15/3/5.
|
||||
// Copyright (c) 2015年 itcast. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MJRefreshComponent.h"
|
||||
|
||||
typedef enum {
|
||||
MJRefreshFooterStateIdle = 1, // 普通闲置状态
|
||||
MJRefreshFooterStateRefreshing, // 正在刷新中的状态
|
||||
MJRefreshFooterStateNoMoreData // 所有数据加载完毕,没有更多的数据了
|
||||
} MJRefreshFooterState;
|
||||
|
||||
@interface MJRefreshFooter : MJRefreshComponent
|
||||
/** 提示没有更多的数据 */
|
||||
- (void)noticeNoMoreData;
|
||||
/** 重置没有更多的数据(消除没有更多数据的状态) */
|
||||
- (void)resetNoMoreData;
|
||||
|
||||
/** 刷新控件的状态(交给子类重写) */
|
||||
@property (assign, nonatomic) MJRefreshFooterState state;
|
||||
|
||||
/** 是否隐藏状态标签 */
|
||||
@property (assign, nonatomic, getter=isStateHidden) BOOL stateHidden;
|
||||
|
||||
/**
|
||||
* 设置state状态下的状态文字内容title
|
||||
*/
|
||||
- (void)setTitle:(NSString *)title forState:(MJRefreshFooterState)state;
|
||||
|
||||
/** 是否自动刷新(默认为YES) */
|
||||
@property (assign, nonatomic, getter=isAutomaticallyRefresh) BOOL automaticallyRefresh;
|
||||
|
||||
/** 当底部控件出现多少时就自动刷新(默认为1.0,也就是底部控件完全出现时,才会自动刷新) */
|
||||
@property (assign, nonatomic) CGFloat appearencePercentTriggerAutoRefresh;
|
||||
@end
|
||||
+319
@@ -0,0 +1,319 @@
|
||||
// 代码地址: https://github.com/CoderMJLee/MJRefresh
|
||||
// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000
|
||||
// MJRefreshFooter.m
|
||||
// MJRefreshExample
|
||||
//
|
||||
// Created by MJ Lee on 15/3/5.
|
||||
// Copyright (c) 2015年 itcast. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MJRefreshFooter.h"
|
||||
#import "MJRefreshConst.h"
|
||||
#import "UIScrollView+MJExtension.h"
|
||||
#import "MJRefreshHeader.h"
|
||||
#import "UIView+MJExtension.h"
|
||||
#import "UIScrollView+MJRefresh.h"
|
||||
#import <objc/message.h>
|
||||
|
||||
@interface MJRefreshFooter()
|
||||
/** 显示状态文字的标签 */
|
||||
@property (weak, nonatomic) UILabel *stateLabel;
|
||||
/** 点击可以加载更多 */
|
||||
@property (weak, nonatomic) UIButton *loadMoreButton;
|
||||
/** 没有更多的数据 */
|
||||
@property (weak, nonatomic) UILabel *noMoreLabel;
|
||||
/** 即将要执行的代码 */
|
||||
@property (strong, nonatomic) NSMutableArray *willExecuteBlocks;
|
||||
@end
|
||||
|
||||
@implementation MJRefreshFooter
|
||||
#pragma mark - 懒加载
|
||||
- (NSMutableArray *)willExecuteBlocks
|
||||
{
|
||||
if (!_willExecuteBlocks) {
|
||||
self.willExecuteBlocks = [NSMutableArray array];
|
||||
}
|
||||
return _willExecuteBlocks;
|
||||
}
|
||||
|
||||
- (UIButton *)loadMoreButton
|
||||
{
|
||||
if (!_loadMoreButton) {
|
||||
UIButton *loadMoreButton = [[UIButton alloc] init];
|
||||
loadMoreButton.backgroundColor = [UIColor clearColor];
|
||||
[loadMoreButton addTarget:self action:@selector(buttonClick) forControlEvents:UIControlEventTouchUpInside];
|
||||
[self addSubview:_loadMoreButton = loadMoreButton];
|
||||
}
|
||||
return _loadMoreButton;
|
||||
}
|
||||
|
||||
- (UILabel *)noMoreLabel
|
||||
{
|
||||
if (!_noMoreLabel) {
|
||||
UILabel *noMoreLabel = [[UILabel alloc] init];
|
||||
noMoreLabel.backgroundColor = [UIColor clearColor];
|
||||
noMoreLabel.textAlignment = NSTextAlignmentCenter;
|
||||
[self addSubview:_noMoreLabel = noMoreLabel];
|
||||
}
|
||||
return _noMoreLabel;
|
||||
}
|
||||
|
||||
- (UILabel *)stateLabel
|
||||
{
|
||||
if (!_stateLabel) {
|
||||
UILabel *stateLabel = [[UILabel alloc] init];
|
||||
stateLabel.backgroundColor = [UIColor clearColor];
|
||||
stateLabel.textAlignment = NSTextAlignmentCenter;
|
||||
[self addSubview:_stateLabel = stateLabel];
|
||||
}
|
||||
return _stateLabel;
|
||||
}
|
||||
|
||||
#pragma mark - 初始化方法
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
if (self = [super initWithFrame:frame]) {
|
||||
// 默认底部控件100%出现时才会自动刷新
|
||||
self.appearencePercentTriggerAutoRefresh = 1.0;
|
||||
|
||||
// 设置为默认状态
|
||||
self.automaticallyRefresh = YES;
|
||||
self.state = MJRefreshFooterStateIdle;
|
||||
|
||||
// 初始化文字
|
||||
[self setTitle:MJRefreshFooterStateIdleText forState:MJRefreshFooterStateIdle];
|
||||
[self setTitle:MJRefreshFooterStateRefreshingText forState:MJRefreshFooterStateRefreshing];
|
||||
[self setTitle:MJRefreshFooterStateNoMoreDataText forState:MJRefreshFooterStateNoMoreData];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)willMoveToSuperview:(UIView *)newSuperview
|
||||
{
|
||||
[super willMoveToSuperview:newSuperview];
|
||||
|
||||
// 旧的父控件
|
||||
[self.superview removeObserver:self forKeyPath:MJRefreshContentSize context:nil];
|
||||
[self.superview removeObserver:self forKeyPath:MJRefreshPanState context:nil];
|
||||
|
||||
if (newSuperview) { // 新的父控件
|
||||
// 监听
|
||||
[newSuperview addObserver:self forKeyPath:MJRefreshContentSize options:NSKeyValueObservingOptionNew context:nil];
|
||||
[newSuperview addObserver:self forKeyPath:MJRefreshPanState options:NSKeyValueObservingOptionNew context:nil];
|
||||
|
||||
self.mj_h = MJRefreshFooterHeight;
|
||||
_scrollView.mj_insetB += self.mj_h;
|
||||
|
||||
// 重新调整frame
|
||||
[self adjustFrameWithContentSize];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
|
||||
self.loadMoreButton.frame = self.bounds;
|
||||
self.stateLabel.frame = self.bounds;
|
||||
self.noMoreLabel.frame = self.bounds;
|
||||
}
|
||||
|
||||
#pragma mark - 私有方法
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
|
||||
{
|
||||
// 遇到这些情况就直接返回
|
||||
if (!self.userInteractionEnabled || self.alpha <= 0.01 || self.hidden) return;
|
||||
|
||||
if (self.state == MJRefreshFooterStateIdle) {
|
||||
// 当是Idle状态时,才需要检测是否要进入刷新状态
|
||||
if ([keyPath isEqualToString:MJRefreshPanState]) {
|
||||
if (_scrollView.panGestureRecognizer.state == UIGestureRecognizerStateEnded) {// 手松开
|
||||
if (_scrollView.mj_insetT + _scrollView.mj_contentSizeH <= _scrollView.mj_h) { // 不够一个屏幕
|
||||
if (_scrollView.mj_offsetY > - _scrollView.mj_insetT) { // 向上拽
|
||||
[self beginRefreshing];
|
||||
}
|
||||
} else { // 超出一个屏幕
|
||||
if (_scrollView.mj_offsetY > _scrollView.mj_contentSizeH + _scrollView.mj_insetB - _scrollView.mj_h) {
|
||||
[self beginRefreshing];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ([keyPath isEqualToString:MJRefreshContentOffset]) {
|
||||
if (self.state != MJRefreshFooterStateRefreshing && self.automaticallyRefresh) {
|
||||
// 根据contentOffset调整state
|
||||
[self adjustStateWithContentOffset];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 不管是什么状态,都要调整位置
|
||||
if ([keyPath isEqualToString:MJRefreshContentSize]) {
|
||||
[self adjustFrameWithContentSize];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark 根据contentOffset调整state
|
||||
- (void)adjustStateWithContentOffset
|
||||
{
|
||||
if (self.mj_y == 0) return;
|
||||
|
||||
if (_scrollView.mj_insetT + _scrollView.mj_contentSizeH > _scrollView.mj_h) { // 内容超过一个屏幕
|
||||
// 这里的_scrollView.mj_contentSizeH替换掉self.mj_y更为合理
|
||||
if (_scrollView.mj_offsetY > _scrollView.mj_contentSizeH - _scrollView.mj_h + self.mj_h * self.appearencePercentTriggerAutoRefresh + _scrollView.mj_insetB - self.mj_h) {
|
||||
// 当底部刷新控件完全出现时,才刷新
|
||||
[self beginRefreshing];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)adjustFrameWithContentSize
|
||||
{
|
||||
// 设置位置
|
||||
self.mj_y = _scrollView.mj_contentSizeH;
|
||||
}
|
||||
|
||||
- (void)buttonClick
|
||||
{
|
||||
[self beginRefreshing];
|
||||
}
|
||||
|
||||
#pragma mark - 公共方法
|
||||
- (void)setHidden:(BOOL)hidden
|
||||
{
|
||||
__weak typeof(self) weakSelf = self;
|
||||
BOOL lastHidden = weakSelf.isHidden;
|
||||
CGFloat h = weakSelf.mj_h;
|
||||
[weakSelf.willExecuteBlocks addObject:^{
|
||||
if (!lastHidden && hidden) {
|
||||
weakSelf.state = MJRefreshFooterStateIdle;
|
||||
_scrollView.mj_insetB -= h;
|
||||
} else if (lastHidden && !hidden) {
|
||||
_scrollView.mj_insetB += h;
|
||||
|
||||
[weakSelf adjustFrameWithContentSize];
|
||||
}
|
||||
}];
|
||||
[weakSelf setNeedsDisplay]; // 放到drawRect是为了延迟执行,防止因为修改了inset,导致循环调用数据源方法
|
||||
|
||||
[super setHidden:hidden];
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)rect
|
||||
{
|
||||
[super drawRect:rect];
|
||||
|
||||
for (void (^block)() in self.willExecuteBlocks) {
|
||||
block();
|
||||
}
|
||||
[self.willExecuteBlocks removeAllObjects];
|
||||
}
|
||||
|
||||
- (void)beginRefreshing
|
||||
{
|
||||
self.state = MJRefreshFooterStateRefreshing;
|
||||
}
|
||||
|
||||
- (void)endRefreshing
|
||||
{
|
||||
self.state = MJRefreshFooterStateIdle;
|
||||
}
|
||||
|
||||
- (BOOL)isRefreshing
|
||||
{
|
||||
return self.state == MJRefreshFooterStateRefreshing;
|
||||
}
|
||||
|
||||
- (void)noticeNoMoreData
|
||||
{
|
||||
self.state = MJRefreshFooterStateNoMoreData;
|
||||
}
|
||||
|
||||
- (void)resetNoMoreData
|
||||
{
|
||||
self.state = MJRefreshFooterStateIdle;
|
||||
}
|
||||
|
||||
- (void)setTitle:(NSString *)title forState:(MJRefreshFooterState)state
|
||||
{
|
||||
if (title == nil) return;
|
||||
|
||||
// 刷新当前状态的文字
|
||||
switch (state) {
|
||||
case MJRefreshFooterStateIdle:
|
||||
[self.loadMoreButton setTitle:title forState:UIControlStateNormal];
|
||||
break;
|
||||
|
||||
case MJRefreshFooterStateRefreshing:
|
||||
self.stateLabel.text = title;
|
||||
break;
|
||||
|
||||
case MJRefreshFooterStateNoMoreData:
|
||||
self.noMoreLabel.text = title;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setState:(MJRefreshFooterState)state
|
||||
{
|
||||
if (_state == state) return;
|
||||
|
||||
_state = state;
|
||||
|
||||
switch (state) {
|
||||
case MJRefreshFooterStateIdle:
|
||||
self.noMoreLabel.hidden = YES;
|
||||
self.stateLabel.hidden = YES;
|
||||
self.loadMoreButton.hidden = NO;
|
||||
break;
|
||||
|
||||
case MJRefreshFooterStateRefreshing:
|
||||
self.loadMoreButton.hidden = YES;
|
||||
self.noMoreLabel.hidden = YES;
|
||||
if (!self.stateHidden) self.stateLabel.hidden = NO;
|
||||
if (self.refreshingBlock) {
|
||||
self.refreshingBlock();
|
||||
}
|
||||
if ([self.refreshingTarget respondsToSelector:self.refreshingAction]) {
|
||||
msgSend(msgTarget(self.refreshingTarget), self.refreshingAction, self);
|
||||
}
|
||||
break;
|
||||
|
||||
case MJRefreshFooterStateNoMoreData:
|
||||
self.loadMoreButton.hidden = YES;
|
||||
self.noMoreLabel.hidden = NO;
|
||||
self.stateLabel.hidden = YES;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setTextColor:(UIColor *)textColor
|
||||
{
|
||||
[super setTextColor:textColor];
|
||||
|
||||
self.stateLabel.textColor = textColor;
|
||||
[self.loadMoreButton setTitleColor:textColor forState:UIControlStateNormal];
|
||||
self.noMoreLabel.textColor = textColor;
|
||||
}
|
||||
|
||||
- (void)setFont:(UIFont *)font
|
||||
{
|
||||
[super setFont:font];
|
||||
|
||||
self.loadMoreButton.titleLabel.font = font;
|
||||
self.noMoreLabel.font = font;
|
||||
self.stateLabel.font = font;
|
||||
}
|
||||
|
||||
- (void)setStateHidden:(BOOL)stateHidden
|
||||
{
|
||||
_stateHidden = stateHidden;
|
||||
|
||||
self.stateLabel.hidden = stateHidden;
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
@end
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// 代码地址: https://github.com/CoderMJLee/MJRefresh
|
||||
// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000
|
||||
// MJRefreshGifFooter.h
|
||||
// MJRefreshExample
|
||||
//
|
||||
// Created by MJ Lee on 15/3/5.
|
||||
// Copyright (c) 2015年 itcast. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MJRefreshFooter.h"
|
||||
|
||||
@interface MJRefreshGifFooter : MJRefreshFooter
|
||||
/** 正在刷新时的动画图片 */
|
||||
@property (strong, nonatomic) NSArray *refreshingImages;
|
||||
@end
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
// 代码地址: https://github.com/CoderMJLee/MJRefresh
|
||||
// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000
|
||||
// MJRefreshGifFooter.m
|
||||
// MJRefreshExample
|
||||
//
|
||||
// Created by MJ Lee on 15/3/5.
|
||||
// Copyright (c) 2015年 itcast. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MJRefreshGifFooter.h"
|
||||
#import "MJRefreshConst.h"
|
||||
#import "UIView+MJExtension.h"
|
||||
#import "UIScrollView+MJExtension.h"
|
||||
|
||||
@interface MJRefreshGifFooter()
|
||||
/** 播放动画图片的控件 */
|
||||
@property (weak, nonatomic) UIImageView *gifView;
|
||||
@end
|
||||
|
||||
@implementation MJRefreshGifFooter
|
||||
#pragma mark - 懒加载
|
||||
- (UIImageView *)gifView
|
||||
{
|
||||
if (!_gifView) {
|
||||
UIImageView *gifView = [[UIImageView alloc] init];
|
||||
[self addSubview:_gifView = gifView];
|
||||
}
|
||||
return _gifView;
|
||||
}
|
||||
|
||||
#pragma mark - 初始化方法
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
|
||||
// 指示器
|
||||
self.gifView.frame = self.bounds;
|
||||
if (self.stateHidden) {
|
||||
self.gifView.contentMode = UIViewContentModeCenter;
|
||||
} else {
|
||||
self.gifView.contentMode = UIViewContentModeRight;
|
||||
self.gifView.mj_w = self.mj_w * 0.5 - 90;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - 公共方法
|
||||
- (void)setState:(MJRefreshFooterState)state
|
||||
{
|
||||
if (self.state == state) return;
|
||||
|
||||
switch (state) {
|
||||
case MJRefreshFooterStateIdle:
|
||||
self.gifView.hidden = YES;
|
||||
[self.gifView stopAnimating];
|
||||
break;
|
||||
|
||||
case MJRefreshFooterStateRefreshing:
|
||||
self.gifView.hidden = NO;
|
||||
[self.gifView startAnimating];
|
||||
break;
|
||||
|
||||
case MJRefreshFooterStateNoMoreData:
|
||||
self.gifView.hidden = YES;
|
||||
[self.gifView stopAnimating];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// super里面有回调,应该在最后面调用
|
||||
[super setState:state];
|
||||
}
|
||||
|
||||
- (void)setRefreshingImages:(NSArray *)refreshingImages
|
||||
{
|
||||
_refreshingImages = refreshingImages;
|
||||
|
||||
self.gifView.animationImages = refreshingImages;
|
||||
self.gifView.animationDuration = refreshingImages.count * 0.1;
|
||||
|
||||
// 根据图片设置控件的高度
|
||||
UIImage *image = [refreshingImages firstObject];
|
||||
if (image.size.height > self.mj_h) {
|
||||
_scrollView.mj_insetB -= self.mj_h;
|
||||
self.mj_h = image.size.height;
|
||||
_scrollView.mj_insetB += self.mj_h;
|
||||
}
|
||||
}
|
||||
@end
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
// 代码地址: https://github.com/CoderMJLee/MJRefresh
|
||||
// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000
|
||||
// MJRefreshGifHeader.h
|
||||
// MJRefreshExample
|
||||
//
|
||||
// Created by MJ Lee on 15/3/4.
|
||||
// Copyright (c) 2015年 itcast. All rights reserved.
|
||||
// 带有gif图片功能的下拉刷新控件
|
||||
|
||||
#import "MJRefreshHeader.h"
|
||||
|
||||
@interface MJRefreshGifHeader : MJRefreshHeader
|
||||
/** 设置state状态下的动画图片images */
|
||||
- (void)setImages:(NSArray *)images forState:(MJRefreshHeaderState)state;
|
||||
@end
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
// 代码地址: https://github.com/CoderMJLee/MJRefresh
|
||||
// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000
|
||||
// MJRefreshGifHeader.m
|
||||
// MJRefreshExample
|
||||
//
|
||||
// Created by MJ Lee on 15/3/4.
|
||||
// Copyright (c) 2015年 itcast. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MJRefreshGifHeader.h"
|
||||
#import "MJRefreshConst.h"
|
||||
#import "UIView+MJExtension.h"
|
||||
|
||||
@interface MJRefreshGifHeader()
|
||||
/** 所有状态对应的动画图片 */
|
||||
@property (strong, nonatomic) NSMutableDictionary *stateImages;
|
||||
|
||||
/** 播放动画图片的控件 */
|
||||
@property (weak, nonatomic) UIImageView *gifView;
|
||||
@end
|
||||
|
||||
@implementation MJRefreshGifHeader
|
||||
#pragma mark - 懒加载
|
||||
- (NSMutableDictionary *)stateImages
|
||||
{
|
||||
if (!_stateImages) {
|
||||
self.stateImages = [NSMutableDictionary dictionary];
|
||||
}
|
||||
return _stateImages;
|
||||
}
|
||||
|
||||
- (UIImageView *)gifView
|
||||
{
|
||||
if (!_gifView) {
|
||||
UIImageView *gifView = [[UIImageView alloc] init];
|
||||
[self addSubview:_gifView = gifView];
|
||||
}
|
||||
return _gifView;
|
||||
}
|
||||
|
||||
#pragma mark - 初始化
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
|
||||
self.gifView.frame = self.bounds;
|
||||
if (self.stateHidden && self.updatedTimeHidden) {
|
||||
self.gifView.contentMode = UIViewContentModeCenter;
|
||||
} else {
|
||||
self.gifView.contentMode = UIViewContentModeRight;
|
||||
self.gifView.mj_w = self.mj_w * 0.5 - 90;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - 公共方法
|
||||
#pragma mark 设置状态
|
||||
- (void)setState:(MJRefreshHeaderState)state
|
||||
{
|
||||
if (self.state == state) return;
|
||||
|
||||
// 旧状态
|
||||
MJRefreshHeaderState oldState = self.state;
|
||||
|
||||
NSArray *images = self.stateImages[@(state)];
|
||||
if (images.count != 0) {
|
||||
switch (state) {
|
||||
case MJRefreshHeaderStateIdle: {
|
||||
if (oldState == MJRefreshHeaderStateRefreshing) {
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(MJRefreshSlowAnimationDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
self.pullingPercent = 0.0;
|
||||
});
|
||||
} else {
|
||||
self.pullingPercent = self.pullingPercent;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MJRefreshHeaderStatePulling:
|
||||
case MJRefreshHeaderStateRefreshing: {
|
||||
[self.gifView stopAnimating];
|
||||
if (images.count == 1) { // 单张图片
|
||||
self.gifView.image = [images lastObject];
|
||||
} else { // 多张图片
|
||||
self.gifView.animationImages = images;
|
||||
self.gifView.animationDuration = images.count * 0.1;
|
||||
[self.gifView startAnimating];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// super里面有回调,应该在最后面调用
|
||||
[super setState:state];
|
||||
}
|
||||
|
||||
- (void)setPullingPercent:(CGFloat)pullingPercent
|
||||
{
|
||||
[super setPullingPercent:pullingPercent];
|
||||
|
||||
NSArray *images = self.stateImages[@(self.state)];
|
||||
switch (self.state) {
|
||||
case MJRefreshHeaderStateIdle: {
|
||||
[self.gifView stopAnimating];
|
||||
NSUInteger index = images.count * self.pullingPercent;
|
||||
if (index >= images.count) index = images.count - 1;
|
||||
self.gifView.image = images[index];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setImages:(NSArray *)images forState:(MJRefreshHeaderState)state
|
||||
{
|
||||
if (images == nil) return;
|
||||
|
||||
self.stateImages[@(state)] = images;
|
||||
|
||||
// 根据图片设置控件的高度
|
||||
UIImage *image = [images firstObject];
|
||||
if (image.size.height > self.mj_h) {
|
||||
self.mj_h = image.size.height;
|
||||
}
|
||||
}
|
||||
@end
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
// 代码地址: https://github.com/CoderMJLee/MJRefresh
|
||||
// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000
|
||||
// MJRefreshHeader.h
|
||||
// MJRefreshExample
|
||||
//
|
||||
// Created by MJ Lee on 15/3/4.
|
||||
// Copyright (c) 2015年 itcast. All rights reserved.
|
||||
// 下拉刷新控件:负责监控用户下拉的状态
|
||||
|
||||
#import "MJRefreshComponent.h"
|
||||
|
||||
// 下拉刷新控件的状态
|
||||
typedef enum {
|
||||
/** 普通闲置状态 */
|
||||
MJRefreshHeaderStateIdle = 1,
|
||||
/** 松开就可以进行刷新的状态 */
|
||||
MJRefreshHeaderStatePulling,
|
||||
/** 正在刷新中的状态 */
|
||||
MJRefreshHeaderStateRefreshing,
|
||||
/** 即将刷新的状态 */
|
||||
MJRefreshHeaderStateWillRefresh
|
||||
} MJRefreshHeaderState;
|
||||
|
||||
@interface MJRefreshHeader : MJRefreshComponent
|
||||
/** 利用这个key来保存上次的刷新时间(不同界面的刷新控件应该用不同的dateKey,以区分不同界面的刷新时间) */
|
||||
@property (copy, nonatomic) NSString *dateKey;
|
||||
|
||||
/** 利用这个block来决定显示的更新时间 */
|
||||
@property (copy, nonatomic) NSString *(^updatedTimeTitle)(NSDate *updatedTime);
|
||||
|
||||
/**
|
||||
* 设置state状态下的状态文字内容title(别直接拿stateLabel修改文字)
|
||||
*/
|
||||
- (void)setTitle:(NSString *)title forState:(MJRefreshHeaderState)state;
|
||||
/** 刷新控件的状态 */
|
||||
@property (assign, nonatomic) MJRefreshHeaderState state;
|
||||
|
||||
#pragma mark - 文字控件的可见性处理
|
||||
/** 是否隐藏状态标签 */
|
||||
@property (assign, nonatomic, getter=isStateHidden) BOOL stateHidden;
|
||||
/** 是否隐藏刷新时间标签 */
|
||||
@property (assign, nonatomic, getter=isUpdatedTimeHidden) BOOL updatedTimeHidden;
|
||||
|
||||
#pragma mark - 交给子类重写
|
||||
/** 下拉的百分比(交给子类重写) */
|
||||
@property (assign, nonatomic) CGFloat pullingPercent;
|
||||
@end
|
||||
+332
@@ -0,0 +1,332 @@
|
||||
// 代码地址: https://github.com/CoderMJLee/MJRefresh
|
||||
// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000
|
||||
// MJRefreshHeader.m
|
||||
// MJRefreshExample
|
||||
//
|
||||
// Created by MJ Lee on 15/3/4.
|
||||
// Copyright (c) 2015年 itcast. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MJRefreshHeader.h"
|
||||
#import "MJRefreshConst.h"
|
||||
#import "UIView+MJExtension.h"
|
||||
#import <objc/message.h>
|
||||
#import "UIScrollView+MJExtension.h"
|
||||
|
||||
@interface MJRefreshHeader()
|
||||
/** 显示上次刷新时间的标签 */
|
||||
@property (weak, nonatomic) UILabel *updatedTimeLabel;
|
||||
/** 上次刷新时间 */
|
||||
@property (strong, nonatomic) NSDate *updatedTime;
|
||||
/** 显示状态文字的标签 */
|
||||
@property (weak, nonatomic) UILabel *stateLabel;
|
||||
/** 所有状态对应的文字 */
|
||||
@property (strong, nonatomic) NSMutableDictionary *stateTitles;
|
||||
@end
|
||||
|
||||
@implementation MJRefreshHeader
|
||||
#pragma mark - 懒加载
|
||||
- (NSMutableDictionary *)stateTitles
|
||||
{
|
||||
if (!_stateTitles) {
|
||||
self.stateTitles = [NSMutableDictionary dictionary];
|
||||
}
|
||||
return _stateTitles;
|
||||
}
|
||||
|
||||
- (UILabel *)stateLabel
|
||||
{
|
||||
if (!_stateLabel) {
|
||||
UILabel *stateLabel = [[UILabel alloc] init];
|
||||
stateLabel.backgroundColor = [UIColor clearColor];
|
||||
stateLabel.textAlignment = NSTextAlignmentCenter;
|
||||
[self addSubview:_stateLabel = stateLabel];
|
||||
}
|
||||
return _stateLabel;
|
||||
}
|
||||
|
||||
- (UILabel *)updatedTimeLabel
|
||||
{
|
||||
if (!_updatedTimeLabel) {
|
||||
UILabel *updatedTimeLabel = [[UILabel alloc] init];
|
||||
updatedTimeLabel.backgroundColor = [UIColor clearColor];
|
||||
updatedTimeLabel.textAlignment = NSTextAlignmentCenter;
|
||||
[self addSubview:_updatedTimeLabel = updatedTimeLabel];
|
||||
}
|
||||
return _updatedTimeLabel;
|
||||
}
|
||||
|
||||
#pragma mark - 初始化方法
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
if (self = [super initWithFrame:frame]) {
|
||||
// 设置默认的dateKey
|
||||
self.dateKey = MJRefreshHeaderUpdatedTimeKey;
|
||||
|
||||
// 设置为默认状态
|
||||
self.state = MJRefreshHeaderStateIdle;
|
||||
|
||||
// 初始化文字
|
||||
[self setTitle:MJRefreshHeaderStateIdleText forState:MJRefreshHeaderStateIdle];
|
||||
[self setTitle:MJRefreshHeaderStatePullingText forState:MJRefreshHeaderStatePulling];
|
||||
[self setTitle:MJRefreshHeaderStateRefreshingText forState:MJRefreshHeaderStateRefreshing];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)willMoveToSuperview:(UIView *)newSuperview
|
||||
{
|
||||
[super willMoveToSuperview:newSuperview];
|
||||
|
||||
if (newSuperview) {
|
||||
self.mj_h = MJRefreshHeaderHeight;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)rect
|
||||
{
|
||||
if (self.state == MJRefreshHeaderStateWillRefresh) {
|
||||
self.state = MJRefreshHeaderStateRefreshing;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
|
||||
// 设置自己的位置
|
||||
self.mj_y = - self.mj_h;
|
||||
|
||||
// 2个标签都隐藏
|
||||
if (self.stateHidden && self.updatedTimeHidden) return;
|
||||
|
||||
if (self.updatedTimeHidden) { // 显示状态
|
||||
_stateLabel.frame = self.bounds;
|
||||
} else if (self.stateHidden) { // 显示时间
|
||||
self.updatedTimeLabel.frame = self.bounds;
|
||||
} else { // 都显示
|
||||
CGFloat stateH = self.mj_h * 0.55;
|
||||
CGFloat stateW = self.mj_w;
|
||||
// 1.状态标签
|
||||
_stateLabel.frame = CGRectMake(0, 0, stateW, stateH);
|
||||
|
||||
// 2.时间标签
|
||||
CGFloat updatedTimeY = stateH;
|
||||
CGFloat updatedTimeH = self.mj_h - stateH;
|
||||
CGFloat updatedTimeW = stateW;
|
||||
self.updatedTimeLabel.frame = CGRectMake(0, updatedTimeY, updatedTimeW, updatedTimeH);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - 私有方法
|
||||
- (void)setDateKey:(NSString *)dateKey
|
||||
{
|
||||
_dateKey = dateKey ? dateKey : MJRefreshHeaderUpdatedTimeKey;
|
||||
|
||||
self.updatedTime = [[NSUserDefaults standardUserDefaults] objectForKey:_dateKey];
|
||||
}
|
||||
|
||||
#pragma mark 设置最后的更新时间
|
||||
- (void)setUpdatedTime:(NSDate *)updatedTime
|
||||
{
|
||||
_updatedTime = updatedTime;
|
||||
|
||||
if (updatedTime) {
|
||||
[[NSUserDefaults standardUserDefaults] setObject:updatedTime forKey:self.dateKey];
|
||||
[[NSUserDefaults standardUserDefaults] synchronize];
|
||||
}
|
||||
|
||||
if (self.updatedTimeTitle) {
|
||||
self.updatedTimeLabel.text = self.updatedTimeTitle(updatedTime);
|
||||
return;
|
||||
}
|
||||
|
||||
if (updatedTime) {
|
||||
// 1.获得年月日
|
||||
NSCalendar *calendar = [NSCalendar currentCalendar];
|
||||
NSUInteger unitFlags = NSCalendarUnitYear| NSCalendarUnitMonth | NSCalendarUnitDay |NSCalendarUnitHour |NSCalendarUnitMinute;
|
||||
NSDateComponents *cmp1 = [calendar components:unitFlags fromDate:updatedTime];
|
||||
NSDateComponents *cmp2 = [calendar components:unitFlags fromDate:[NSDate date]];
|
||||
|
||||
// 2.格式化日期
|
||||
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
|
||||
if ([cmp1 day] == [cmp2 day]) { // 今天
|
||||
formatter.dateFormat = @"今天 HH:mm";
|
||||
} else if ([cmp1 year] == [cmp2 year]) { // 今年
|
||||
formatter.dateFormat = @"MM-dd HH:mm";
|
||||
} else {
|
||||
formatter.dateFormat = @"yyyy-MM-dd HH:mm";
|
||||
}
|
||||
NSString *time = [formatter stringFromDate:updatedTime];
|
||||
|
||||
// 3.显示日期
|
||||
self.updatedTimeLabel.text = [NSString stringWithFormat:@"最后更新:%@", time];
|
||||
} else {
|
||||
self.updatedTimeLabel.text = @"最后更新:无记录";
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark KVO属性监听
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
|
||||
{
|
||||
// 遇到这些情况就直接返回
|
||||
if (!self.userInteractionEnabled || self.alpha <= 0.01 || self.hidden || self.state == MJRefreshHeaderStateRefreshing) return;
|
||||
|
||||
// 根据contentOffset调整state
|
||||
if ([keyPath isEqualToString:MJRefreshContentOffset]) {
|
||||
[self adjustStateWithContentOffset];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark 根据contentOffset调整state
|
||||
- (void)adjustStateWithContentOffset
|
||||
{
|
||||
if (self.state != MJRefreshHeaderStateRefreshing) {
|
||||
// 在刷新过程中,跳转到下一个控制器时,contentInset可能会变
|
||||
_scrollViewOriginalInset = _scrollView.contentInset;
|
||||
}
|
||||
|
||||
// 当前的contentOffset
|
||||
CGFloat offsetY = _scrollView.mj_offsetY;
|
||||
// 头部控件刚好出现的offsetY
|
||||
CGFloat happenOffsetY = - _scrollViewOriginalInset.top;
|
||||
|
||||
// 如果是向上滚动到看不见头部控件,直接返回
|
||||
if (offsetY >= happenOffsetY) return;
|
||||
|
||||
// 普通 和 即将刷新 的临界点
|
||||
CGFloat normal2pullingOffsetY = happenOffsetY - self.mj_h;
|
||||
if (_scrollView.isDragging) {
|
||||
self.pullingPercent = (happenOffsetY - offsetY) / self.mj_h;
|
||||
|
||||
if (self.state == MJRefreshHeaderStateIdle && offsetY < normal2pullingOffsetY) {
|
||||
// 转为即将刷新状态
|
||||
self.state = MJRefreshHeaderStatePulling;
|
||||
} else if (self.state == MJRefreshHeaderStatePulling && offsetY >= normal2pullingOffsetY) {
|
||||
// 转为普通状态
|
||||
self.state = MJRefreshHeaderStateIdle;
|
||||
}
|
||||
} else if (self.state == MJRefreshHeaderStatePulling) {// 即将刷新 && 手松开
|
||||
self.pullingPercent = 1.0;
|
||||
// 开始刷新
|
||||
self.state = MJRefreshHeaderStateRefreshing;
|
||||
} else {
|
||||
self.pullingPercent = (happenOffsetY - offsetY) / self.mj_h;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - 公共方法
|
||||
- (void)setTitle:(NSString *)title forState:(MJRefreshHeaderState)state
|
||||
{
|
||||
if (title == nil) return;
|
||||
self.stateTitles[@(state)] = title;
|
||||
|
||||
// 刷新当前状态的文字
|
||||
self.stateLabel.text = self.stateTitles[@(self.state)];
|
||||
}
|
||||
|
||||
- (void)beginRefreshing
|
||||
{
|
||||
if (self.window) {
|
||||
self.state = MJRefreshHeaderStateRefreshing;
|
||||
} else {
|
||||
self.state = MJRefreshHeaderStateWillRefresh;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)endRefreshing
|
||||
{
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.05 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
self.state = MJRefreshHeaderStateIdle;
|
||||
});
|
||||
}
|
||||
|
||||
- (BOOL)isRefreshing
|
||||
{
|
||||
return self.state == MJRefreshHeaderStateRefreshing;
|
||||
}
|
||||
|
||||
- (void)setState:(MJRefreshHeaderState)state
|
||||
{
|
||||
if (_state == state) return;
|
||||
|
||||
// 旧状态
|
||||
MJRefreshHeaderState oldState = _state;
|
||||
|
||||
// 赋值
|
||||
_state = state;
|
||||
|
||||
// 设置状态文字
|
||||
_stateLabel.text = _stateTitles[@(state)];
|
||||
|
||||
switch (state) {
|
||||
case MJRefreshHeaderStateIdle: {
|
||||
if (oldState == MJRefreshHeaderStateRefreshing) {
|
||||
// 保存刷新时间
|
||||
self.updatedTime = [NSDate date];
|
||||
|
||||
// 恢复inset和offset
|
||||
[UIView animateWithDuration:MJRefreshSlowAnimationDuration delay:0.0 options:UIViewAnimationOptionAllowUserInteraction|UIViewAnimationOptionBeginFromCurrentState animations:^{
|
||||
_scrollView.mj_insetT -= self.mj_h;
|
||||
} completion:nil];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MJRefreshHeaderStateRefreshing: {
|
||||
[UIView animateWithDuration:MJRefreshFastAnimationDuration delay:0.0 options:UIViewAnimationOptionAllowUserInteraction|UIViewAnimationOptionBeginFromCurrentState animations:^{
|
||||
// 增加滚动区域
|
||||
CGFloat top = _scrollViewOriginalInset.top + self.mj_h;
|
||||
_scrollView.mj_insetT = top;
|
||||
|
||||
// 设置滚动位置
|
||||
_scrollView.mj_offsetY = - top;
|
||||
} completion:^(BOOL finished) {
|
||||
// 回调
|
||||
if (self.refreshingBlock) {
|
||||
self.refreshingBlock();
|
||||
}
|
||||
|
||||
if ([self.refreshingTarget respondsToSelector:self.refreshingAction]) {
|
||||
msgSend(msgTarget(self.refreshingTarget), self.refreshingAction, self);
|
||||
}
|
||||
}];
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setTextColor:(UIColor *)textColor
|
||||
{
|
||||
[super setTextColor:textColor];
|
||||
|
||||
self.updatedTimeLabel.textColor = textColor;
|
||||
self.stateLabel.textColor = textColor;
|
||||
}
|
||||
|
||||
- (void)setFont:(UIFont *)font
|
||||
{
|
||||
[super setFont:font];
|
||||
|
||||
self.updatedTimeLabel.font = font;
|
||||
self.stateLabel.font = font;
|
||||
}
|
||||
|
||||
- (void)setStateHidden:(BOOL)stateHidden
|
||||
{
|
||||
_stateHidden = stateHidden;
|
||||
|
||||
self.stateLabel.hidden = stateHidden;
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
- (void)setUpdatedTimeHidden:(BOOL)updatedTimeHidden
|
||||
{
|
||||
_updatedTimeHidden = updatedTimeHidden;
|
||||
|
||||
self.updatedTimeLabel.hidden = updatedTimeHidden;
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
@end
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// 代码地址: https://github.com/CoderMJLee/MJRefresh
|
||||
// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000
|
||||
// MJRefreshLegendFooter.h
|
||||
// MJRefreshExample
|
||||
//
|
||||
// Created by MJ Lee on 15/3/5.
|
||||
// Copyright (c) 2015年 itcast. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MJRefreshFooter.h"
|
||||
|
||||
@interface MJRefreshLegendFooter : MJRefreshFooter
|
||||
|
||||
@end
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
// 代码地址: https://github.com/CoderMJLee/MJRefresh
|
||||
// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000
|
||||
// MJRefreshLegendFooter.m
|
||||
// MJRefreshExample
|
||||
//
|
||||
// Created by MJ Lee on 15/3/5.
|
||||
// Copyright (c) 2015年 itcast. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MJRefreshLegendFooter.h"
|
||||
#import "MJRefreshConst.h"
|
||||
#import "UIView+MJExtension.h"
|
||||
#import "UIScrollView+MJExtension.h"
|
||||
|
||||
@interface MJRefreshLegendFooter()
|
||||
@property (nonatomic, weak) UIActivityIndicatorView *activityView;
|
||||
@end
|
||||
|
||||
@implementation MJRefreshLegendFooter
|
||||
#pragma mark - 懒加载
|
||||
- (UIActivityIndicatorView *)activityView
|
||||
{
|
||||
if (!_activityView) {
|
||||
UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
|
||||
[self addSubview:_activityView = activityView];
|
||||
}
|
||||
return _activityView;
|
||||
}
|
||||
|
||||
#pragma mark - 初始化方法
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
|
||||
// 指示器
|
||||
if (self.stateHidden) {
|
||||
self.activityView.center = CGPointMake(self.mj_w * 0.5, self.mj_h * 0.5);
|
||||
} else {
|
||||
self.activityView.center = CGPointMake(self.mj_w * 0.5 - 100, self.mj_h * 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - 公共方法
|
||||
- (void)setState:(MJRefreshFooterState)state
|
||||
{
|
||||
if (self.state == state) return;
|
||||
|
||||
switch (state) {
|
||||
case MJRefreshFooterStateIdle:
|
||||
[self.activityView stopAnimating];
|
||||
break;
|
||||
|
||||
case MJRefreshFooterStateRefreshing:
|
||||
[self.activityView startAnimating];
|
||||
break;
|
||||
|
||||
case MJRefreshFooterStateNoMoreData:
|
||||
[self.activityView stopAnimating];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// super里面有回调,应该在最后面调用
|
||||
[super setState:state];
|
||||
}
|
||||
@end
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// 代码地址: https://github.com/CoderMJLee/MJRefresh
|
||||
// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000
|
||||
// MJRefreshLegendHeader.h
|
||||
// MJRefreshExample
|
||||
//
|
||||
// Created by MJ Lee on 15/3/4.
|
||||
// Copyright (c) 2015年 itcast. All rights reserved.
|
||||
// 传统的下拉刷新控件:箭头 + 圈圈
|
||||
|
||||
#import "MJRefreshHeader.h"
|
||||
|
||||
@interface MJRefreshLegendHeader : MJRefreshHeader
|
||||
|
||||
@end
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
// 代码地址: https://github.com/CoderMJLee/MJRefresh
|
||||
// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000
|
||||
// MJRefreshLegendHeader.m
|
||||
// MJRefreshExample
|
||||
//
|
||||
// Created by MJ Lee on 15/3/4.
|
||||
// Copyright (c) 2015年 itcast. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MJRefreshLegendHeader.h"
|
||||
#import "MJRefreshConst.h"
|
||||
#import "UIView+MJExtension.h"
|
||||
|
||||
@interface MJRefreshLegendHeader()
|
||||
@property (nonatomic, weak) UIImageView *arrowImage;
|
||||
@property (nonatomic, weak) UIActivityIndicatorView *activityView;
|
||||
@end
|
||||
|
||||
@implementation MJRefreshLegendHeader
|
||||
#pragma mark - 懒加载
|
||||
- (UIImageView *)arrowImage
|
||||
{
|
||||
if (!_arrowImage) {
|
||||
UIImageView *arrowImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:MJRefreshSrcName(@"arrow.png")]];
|
||||
[self addSubview:_arrowImage = arrowImage];
|
||||
}
|
||||
return _arrowImage;
|
||||
}
|
||||
|
||||
- (UIActivityIndicatorView *)activityView
|
||||
{
|
||||
if (!_activityView) {
|
||||
UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
|
||||
activityView.bounds = self.arrowImage.bounds;
|
||||
[self addSubview:_activityView = activityView];
|
||||
}
|
||||
return _activityView;
|
||||
}
|
||||
|
||||
#pragma mark - 初始化
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
|
||||
// 箭头
|
||||
CGFloat arrowX = (self.stateHidden && self.updatedTimeHidden) ? self.mj_w * 0.5 : (self.mj_w * 0.5 - 100);
|
||||
self.arrowImage.center = CGPointMake(arrowX, self.mj_h * 0.5);
|
||||
|
||||
// 指示器
|
||||
self.activityView.center = self.arrowImage.center;
|
||||
}
|
||||
|
||||
#pragma mark - 公共方法
|
||||
#pragma mark 设置状态
|
||||
- (void)setState:(MJRefreshHeaderState)state
|
||||
{
|
||||
if (self.state == state) return;
|
||||
|
||||
// 旧状态
|
||||
MJRefreshHeaderState oldState = self.state;
|
||||
|
||||
switch (state) {
|
||||
case MJRefreshHeaderStateIdle: {
|
||||
if (oldState == MJRefreshHeaderStateRefreshing) {
|
||||
self.arrowImage.transform = CGAffineTransformIdentity;
|
||||
|
||||
[UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{
|
||||
self.activityView.alpha = 0.0;
|
||||
} completion:^(BOOL finished) {
|
||||
self.arrowImage.alpha = 1.0;
|
||||
self.activityView.alpha = 1.0;
|
||||
[self.activityView stopAnimating];
|
||||
}];
|
||||
} else {
|
||||
[UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{
|
||||
self.arrowImage.transform = CGAffineTransformIdentity;
|
||||
}];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MJRefreshHeaderStatePulling: {
|
||||
[UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{
|
||||
self.arrowImage.transform = CGAffineTransformMakeRotation(0.000001 - M_PI);
|
||||
}];
|
||||
break;
|
||||
}
|
||||
|
||||
case MJRefreshHeaderStateRefreshing: {
|
||||
[self.activityView startAnimating];
|
||||
self.arrowImage.alpha = 0.0;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// super里面有回调,应该在最后面调用
|
||||
[super setState:state];
|
||||
}
|
||||
|
||||
@end
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
// 代码地址: https://github.com/CoderMJLee/MJRefresh
|
||||
// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000
|
||||
// UIScrollView+Extension.h
|
||||
// MJRefreshExample
|
||||
//
|
||||
// Created by MJ Lee on 14-5-28.
|
||||
// Copyright (c) 2014年 itcast. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface UIScrollView (MJExtension)
|
||||
@property (assign, nonatomic) CGFloat mj_insetT;
|
||||
@property (assign, nonatomic) CGFloat mj_insetB;
|
||||
@property (assign, nonatomic) CGFloat mj_insetL;
|
||||
@property (assign, nonatomic) CGFloat mj_insetR;
|
||||
|
||||
@property (assign, nonatomic) CGFloat mj_offsetX;
|
||||
@property (assign, nonatomic) CGFloat mj_offsetY;
|
||||
|
||||
@property (assign, nonatomic) CGFloat mj_contentSizeW;
|
||||
@property (assign, nonatomic) CGFloat mj_contentSizeH;
|
||||
@end
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
// 代码地址: https://github.com/CoderMJLee/MJRefresh
|
||||
// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000
|
||||
// UIScrollView+Extension.m
|
||||
// MJRefreshExample
|
||||
//
|
||||
// Created by MJ Lee on 14-5-28.
|
||||
// Copyright (c) 2014年 itcast. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UIScrollView+MJExtension.h"
|
||||
|
||||
@implementation UIScrollView (MJExtension)
|
||||
- (void)setMj_insetT:(CGFloat)mj_insetT
|
||||
{
|
||||
UIEdgeInsets inset = self.contentInset;
|
||||
inset.top = mj_insetT;
|
||||
self.contentInset = inset;
|
||||
}
|
||||
|
||||
- (CGFloat)mj_insetT
|
||||
{
|
||||
return self.contentInset.top;
|
||||
}
|
||||
|
||||
- (void)setMj_insetB:(CGFloat)mj_insetB
|
||||
{
|
||||
UIEdgeInsets inset = self.contentInset;
|
||||
inset.bottom = mj_insetB;
|
||||
self.contentInset = inset;
|
||||
}
|
||||
|
||||
- (CGFloat)mj_insetB
|
||||
{
|
||||
return self.contentInset.bottom;
|
||||
}
|
||||
|
||||
- (void)setMj_insetL:(CGFloat)mj_insetL
|
||||
{
|
||||
UIEdgeInsets inset = self.contentInset;
|
||||
inset.left = mj_insetL;
|
||||
self.contentInset = inset;
|
||||
}
|
||||
|
||||
- (CGFloat)mj_insetL
|
||||
{
|
||||
return self.contentInset.left;
|
||||
}
|
||||
|
||||
- (void)setMj_insetR:(CGFloat)mj_insetR
|
||||
{
|
||||
UIEdgeInsets inset = self.contentInset;
|
||||
inset.right = mj_insetR;
|
||||
self.contentInset = inset;
|
||||
}
|
||||
|
||||
- (CGFloat)mj_insetR
|
||||
{
|
||||
return self.contentInset.right;
|
||||
}
|
||||
|
||||
- (void)setMj_offsetX:(CGFloat)mj_offsetX
|
||||
{
|
||||
CGPoint offset = self.contentOffset;
|
||||
offset.x = mj_offsetX;
|
||||
self.contentOffset = offset;
|
||||
}
|
||||
|
||||
- (CGFloat)mj_offsetX
|
||||
{
|
||||
return self.contentOffset.x;
|
||||
}
|
||||
|
||||
- (void)setMj_offsetY:(CGFloat)mj_offsetY
|
||||
{
|
||||
CGPoint offset = self.contentOffset;
|
||||
offset.y = mj_offsetY;
|
||||
self.contentOffset = offset;
|
||||
}
|
||||
|
||||
- (CGFloat)mj_offsetY
|
||||
{
|
||||
return self.contentOffset.y;
|
||||
}
|
||||
|
||||
- (void)setMj_contentSizeW:(CGFloat)mj_contentSizeW
|
||||
{
|
||||
CGSize size = self.contentSize;
|
||||
size.width = mj_contentSizeW;
|
||||
self.contentSize = size;
|
||||
}
|
||||
|
||||
- (CGFloat)mj_contentSizeW
|
||||
{
|
||||
return self.contentSize.width;
|
||||
}
|
||||
|
||||
- (void)setMj_contentSizeH:(CGFloat)mj_contentSizeH
|
||||
{
|
||||
CGSize size = self.contentSize;
|
||||
size.height = mj_contentSizeH;
|
||||
self.contentSize = size;
|
||||
}
|
||||
|
||||
- (CGFloat)mj_contentSizeH
|
||||
{
|
||||
return self.contentSize.height;
|
||||
}
|
||||
@end
|
||||
+222
@@ -0,0 +1,222 @@
|
||||
// 代码地址: https://github.com/CoderMJLee/MJRefresh
|
||||
// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000
|
||||
// UIScrollView+MJRefresh.h
|
||||
// MJRefreshExample
|
||||
//
|
||||
// Created by MJ Lee on 15/3/4.
|
||||
// Copyright (c) 2015年 itcast. All rights reserved.
|
||||
// 给ScrollView增加下拉刷新、上拉刷新的功能
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "MJRefreshConst.h"
|
||||
|
||||
@class MJRefreshGifHeader, MJRefreshLegendHeader, MJRefreshHeader;
|
||||
@class MJRefreshGifFooter, MJRefreshLegendFooter, MJRefreshFooter;
|
||||
|
||||
@interface UIScrollView (MJRefresh)
|
||||
#pragma mark - 访问下拉刷新控件
|
||||
/** 下拉刷新控件 */
|
||||
@property (strong, nonatomic, readonly) MJRefreshHeader *header;
|
||||
/** gif功能的下拉刷新控件 */
|
||||
@property (nonatomic, readonly) MJRefreshGifHeader *gifHeader;
|
||||
/** 传统的下拉刷新控件 */
|
||||
@property (nonatomic, readonly) MJRefreshLegendHeader *legendHeader;
|
||||
|
||||
#pragma mark - 添加下拉刷新控件
|
||||
/**
|
||||
* 添加一个传统的下拉刷新控件
|
||||
*
|
||||
* @param block 进入刷新状态就会自动调用这个block
|
||||
*/
|
||||
- (MJRefreshLegendHeader *)addLegendHeaderWithRefreshingBlock:(void (^)())block;
|
||||
/**
|
||||
* 添加一个传统的下拉刷新控件
|
||||
*
|
||||
* @param block 进入刷新状态就会自动调用这个block
|
||||
* @param dateKey 用来记录刷新时间的key
|
||||
*/
|
||||
- (MJRefreshLegendHeader *)addLegendHeaderWithRefreshingBlock:(void (^)())block dateKey:(NSString *)dateKey;
|
||||
/**
|
||||
* 添加一个传统的下拉刷新控件
|
||||
*
|
||||
* @param target 进入刷新状态就会自动调用target对象的action方法
|
||||
* @param action 进入刷新状态就会自动调用target对象的action方法
|
||||
*/
|
||||
- (MJRefreshLegendHeader *)addLegendHeaderWithRefreshingTarget:(id)target refreshingAction:(SEL)action;
|
||||
/**
|
||||
* 添加一个传统的下拉刷新控件
|
||||
*
|
||||
* @param target 进入刷新状态就会自动调用target对象的action方法
|
||||
* @param action 进入刷新状态就会自动调用target对象的action方法
|
||||
* @param dateKey 用来记录刷新时间的key
|
||||
*/
|
||||
- (MJRefreshLegendHeader *)addLegendHeaderWithRefreshingTarget:(id)target refreshingAction:(SEL)action dateKey:(NSString *)dateKey;
|
||||
/**
|
||||
* 添加一个gif图片的下拉刷新控件
|
||||
*
|
||||
* @param block 进入刷新状态就会自动调用这个block
|
||||
*/
|
||||
- (MJRefreshGifHeader *)addGifHeaderWithRefreshingBlock:(void (^)())block;
|
||||
/**
|
||||
* 添加一个gif图片的下拉刷新控件
|
||||
*
|
||||
* @param block 进入刷新状态就会自动调用这个block
|
||||
* @param dateKey 用来记录刷新时间的key
|
||||
*/
|
||||
- (MJRefreshGifHeader *)addGifHeaderWithRefreshingBlock:(void (^)())block dateKey:(NSString *)dateKey;
|
||||
/**
|
||||
* 添加一个gif图片的下拉刷新控件
|
||||
*
|
||||
* @param target 进入刷新状态就会自动调用target对象的action方法
|
||||
* @param action 进入刷新状态就会自动调用target对象的action方法
|
||||
*/
|
||||
- (MJRefreshGifHeader *)addGifHeaderWithRefreshingTarget:(id)target refreshingAction:(SEL)action;
|
||||
/**
|
||||
* 添加一个gif图片的下拉刷新控件
|
||||
*
|
||||
* @param target 进入刷新状态就会自动调用target对象的action方法
|
||||
* @param action 进入刷新状态就会自动调用target对象的action方法
|
||||
* @param dateKey 用来记录刷新时间的key
|
||||
*/
|
||||
- (MJRefreshGifHeader *)addGifHeaderWithRefreshingTarget:(id)target refreshingAction:(SEL)action dateKey:(NSString *)dateKey;
|
||||
|
||||
#pragma mark - 移除下拉刷新控件
|
||||
/**
|
||||
* 移除下拉刷新控件
|
||||
*/
|
||||
- (void)removeHeader;
|
||||
|
||||
#pragma mark - 访问上拉刷新控件
|
||||
/** 上拉刷新控件 */
|
||||
@property (strong, nonatomic, readonly) MJRefreshFooter *footer;
|
||||
/** gif功能的上拉刷新控件 */
|
||||
@property (nonatomic, readonly) MJRefreshGifFooter *gifFooter;
|
||||
/** 传统的上拉刷新控件 */
|
||||
@property (nonatomic, readonly) MJRefreshLegendFooter *legendFooter;
|
||||
|
||||
#pragma mark - 添加上拉刷新控件
|
||||
/**
|
||||
* 添加一个传统的上拉刷新控件
|
||||
*
|
||||
* @param block 进入刷新状态就会自动调用这个block
|
||||
*/
|
||||
- (MJRefreshLegendFooter *)addLegendFooterWithRefreshingBlock:(void (^)())block;
|
||||
/**
|
||||
* 添加一个传统的上拉刷新控件
|
||||
*
|
||||
* @param target 进入刷新状态就会自动调用target对象的action方法
|
||||
* @param action 进入刷新状态就会自动调用target对象的action方法
|
||||
*/
|
||||
- (MJRefreshLegendFooter *)addLegendFooterWithRefreshingTarget:(id)target refreshingAction:(SEL)action;
|
||||
/**
|
||||
* 添加一个gif图片的上拉刷新控件
|
||||
*
|
||||
* @param block 进入刷新状态就会自动调用这个block
|
||||
*/
|
||||
- (MJRefreshGifFooter *)addGifFooterWithRefreshingBlock:(void (^)())block;
|
||||
/**
|
||||
* 添加一个gif图片的上拉刷新控件
|
||||
*
|
||||
* @param target 进入刷新状态就会自动调用target对象的action方法
|
||||
* @param action 进入刷新状态就会自动调用target对象的action方法
|
||||
*/
|
||||
- (MJRefreshGifFooter *)addGifFooterWithRefreshingTarget:(id)target refreshingAction:(SEL)action;
|
||||
|
||||
#pragma mark - 移除上拉刷新控件
|
||||
/**
|
||||
* 移除上拉刷新控件
|
||||
*/
|
||||
- (void)removeFooter;
|
||||
@end
|
||||
|
||||
#pragma mark - 1.0.0版本以前的接口
|
||||
@interface UIScrollView(MJRefreshDeprecated)
|
||||
#pragma mark - 下拉刷新
|
||||
/**
|
||||
* 添加一个下拉刷新头部控件
|
||||
*
|
||||
* @param callback 回调
|
||||
*/
|
||||
- (void)addHeaderWithCallback:(void (^)())callback MJDeprecated("建议使用addLegendHeaderWithRefreshingBlock:");
|
||||
|
||||
/**
|
||||
* 添加一个下拉刷新头部控件
|
||||
*
|
||||
* @param callback 回调
|
||||
* @param dateKey 刷新时间保存的key值
|
||||
*/
|
||||
- (void)addHeaderWithCallback:(void (^)())callback dateKey:(NSString*)dateKey MJDeprecated("建议使用addLegendHeaderWithRefreshingBlock:dateKey:");
|
||||
|
||||
/**
|
||||
* 添加一个下拉刷新头部控件
|
||||
*
|
||||
* @param target 目标
|
||||
* @param action 回调方法
|
||||
*/
|
||||
- (void)addHeaderWithTarget:(id)target action:(SEL)action MJDeprecated("建议使用addLegendHeaderWithRefreshingTarget:refreshingAction:");
|
||||
|
||||
/**
|
||||
* 添加一个下拉刷新头部控件
|
||||
*
|
||||
* @param target 目标
|
||||
* @param action 回调方法
|
||||
* @param dateKey 刷新时间保存的key值
|
||||
*/
|
||||
- (void)addHeaderWithTarget:(id)target action:(SEL)action dateKey:(NSString*)dateKey MJDeprecated("建议使用addLegendHeaderWithRefreshingTarget:refreshingAction:dateKey:");
|
||||
|
||||
/**
|
||||
* 主动让下拉刷新头部控件进入刷新状态
|
||||
*/
|
||||
- (void)headerBeginRefreshing MJDeprecated("建议使用[self.tableView.header beginRefreshing]");
|
||||
|
||||
/**
|
||||
* 让下拉刷新头部控件停止刷新状态
|
||||
*/
|
||||
- (void)headerEndRefreshing MJDeprecated("建议使用[self.tableView.header endRefreshing]");
|
||||
|
||||
/**
|
||||
* 下拉刷新头部控件的可见性
|
||||
*/
|
||||
@property (nonatomic, assign, getter = isHeaderHidden) BOOL headerHidden MJDeprecated("建议使用self.tableView.header.hidden");
|
||||
|
||||
/**
|
||||
* 是否正在下拉刷新
|
||||
*/
|
||||
@property (nonatomic, assign, readonly, getter = isHeaderRefreshing) BOOL headerRefreshing MJDeprecated("建议使用self.tableView.header.isRefreshing");
|
||||
|
||||
#pragma mark - 上拉刷新
|
||||
/**
|
||||
* 添加一个上拉刷新尾部控件
|
||||
*
|
||||
* @param callback 回调
|
||||
*/
|
||||
- (void)addFooterWithCallback:(void (^)())callback MJDeprecated("建议使用addLegendFooterWithRefreshingBlock:");
|
||||
|
||||
/**
|
||||
* 添加一个上拉刷新尾部控件
|
||||
*
|
||||
* @param target 目标
|
||||
* @param action 回调方法
|
||||
*/
|
||||
- (void)addFooterWithTarget:(id)target action:(SEL)action MJDeprecated("建议使用addLegendFooterWithRefreshingTarget:refreshingAction:");
|
||||
|
||||
/**
|
||||
* 主动让上拉刷新尾部控件进入刷新状态
|
||||
*/
|
||||
- (void)footerBeginRefreshing MJDeprecated("建议使用[self.tableView.footer beginRefreshing]");
|
||||
|
||||
/**
|
||||
* 让上拉刷新尾部控件停止刷新状态
|
||||
*/
|
||||
- (void)footerEndRefreshing MJDeprecated("建议使用[self.tableView.footer endRefreshing]");
|
||||
|
||||
/**
|
||||
* 上拉刷新头部控件的可见性
|
||||
*/
|
||||
@property (nonatomic, assign, getter = isFooterHidden) BOOL footerHidden MJDeprecated("建议使用self.tableView.footer.hidden");
|
||||
|
||||
/**
|
||||
* 是否正在上拉刷新
|
||||
*/
|
||||
@property (nonatomic, assign, readonly, getter = isFooterRefreshing) BOOL footerRefreshing MJDeprecated("建议使用self.tableView.footer.isRefreshing");
|
||||
@end
|
||||
+394
@@ -0,0 +1,394 @@
|
||||
// 代码地址: https://github.com/CoderMJLee/MJRefresh
|
||||
// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000
|
||||
// UIScrollView+MJRefresh.m
|
||||
// MJRefreshExample
|
||||
//
|
||||
// Created by MJ Lee on 15/3/4.
|
||||
// Copyright (c) 2015年 itcast. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UIScrollView+MJRefresh.h"
|
||||
#import "MJRefreshGifHeader.h"
|
||||
#import "MJRefreshLegendHeader.h"
|
||||
#import "MJRefreshGifFooter.h"
|
||||
#import "MJRefreshLegendFooter.h"
|
||||
#import <objc/runtime.h>
|
||||
|
||||
@implementation UIScrollView (MJRefresh)
|
||||
#pragma mark - 下拉刷新
|
||||
- (MJRefreshLegendHeader *)addLegendHeaderWithRefreshingBlock:(void (^)())block dateKey:(NSString *)dateKey
|
||||
{
|
||||
MJRefreshLegendHeader *header = [self addLegendHeader];
|
||||
header.refreshingBlock = block;
|
||||
header.dateKey = dateKey;
|
||||
return header;
|
||||
}
|
||||
|
||||
- (MJRefreshLegendHeader *)addLegendHeaderWithRefreshingTarget:(id)target refreshingAction:(SEL)action dateKey:(NSString *)dateKey
|
||||
{
|
||||
MJRefreshLegendHeader *header = [self addLegendHeader];
|
||||
header.refreshingTarget = target;
|
||||
header.refreshingAction = action;
|
||||
header.dateKey = dateKey;
|
||||
return header;
|
||||
}
|
||||
|
||||
- (MJRefreshLegendHeader *)addLegendHeaderWithRefreshingTarget:(id)target refreshingAction:(SEL)action
|
||||
{
|
||||
return [self addLegendHeaderWithRefreshingTarget:target refreshingAction:action dateKey:nil];
|
||||
}
|
||||
|
||||
- (MJRefreshLegendHeader *)addLegendHeaderWithRefreshingBlock:(void (^)())block
|
||||
{
|
||||
return [self addLegendHeaderWithRefreshingBlock:block dateKey:nil];
|
||||
}
|
||||
|
||||
- (MJRefreshLegendHeader *)addLegendHeader
|
||||
{
|
||||
MJRefreshLegendHeader *header = [[MJRefreshLegendHeader alloc] init];
|
||||
self.header = header;
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
- (MJRefreshGifHeader *)addGifHeaderWithRefreshingBlock:(void (^)())block dateKey:(NSString *)dateKey
|
||||
{
|
||||
MJRefreshGifHeader *header = [self addGifHeader];
|
||||
header.refreshingBlock = block;
|
||||
header.dateKey = dateKey;
|
||||
return header;
|
||||
}
|
||||
|
||||
- (MJRefreshGifHeader *)addGifHeaderWithRefreshingTarget:(id)target refreshingAction:(SEL)action dateKey:(NSString *)dateKey
|
||||
{
|
||||
MJRefreshGifHeader *header = [self addGifHeader];
|
||||
header.refreshingTarget = target;
|
||||
header.refreshingAction = action;
|
||||
header.dateKey = dateKey;
|
||||
return header;
|
||||
}
|
||||
|
||||
- (MJRefreshGifHeader *)addGifHeaderWithRefreshingBlock:(void (^)())block
|
||||
{
|
||||
return [self addGifHeaderWithRefreshingBlock:block dateKey:nil];
|
||||
}
|
||||
|
||||
- (MJRefreshGifHeader *)addGifHeaderWithRefreshingTarget:(id)target refreshingAction:(SEL)action
|
||||
{
|
||||
return [self addGifHeaderWithRefreshingTarget:target refreshingAction:action dateKey:nil];
|
||||
}
|
||||
|
||||
- (MJRefreshGifHeader *)addGifHeader
|
||||
{
|
||||
MJRefreshGifHeader *header = [[MJRefreshGifHeader alloc] init];
|
||||
self.header = header;
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
- (void)removeHeader
|
||||
{
|
||||
self.header = nil;
|
||||
}
|
||||
|
||||
#pragma mark - Property Methods
|
||||
#pragma mark gifHeader
|
||||
- (MJRefreshGifHeader *)gifHeader
|
||||
{
|
||||
if ([self.header isKindOfClass:[MJRefreshGifHeader class]]) {
|
||||
return (MJRefreshGifHeader *)self.header;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
#pragma mark legendHeader
|
||||
- (MJRefreshLegendHeader *)legendHeader
|
||||
{
|
||||
if ([self.header isKindOfClass:[MJRefreshLegendHeader class]]) {
|
||||
return (MJRefreshLegendHeader *)self.header;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
#pragma mark header
|
||||
static char MJRefreshHeaderKey;
|
||||
- (void)setHeader:(MJRefreshHeader *)header
|
||||
{
|
||||
if (header != self.header) {
|
||||
[self.header removeFromSuperview];
|
||||
|
||||
[self willChangeValueForKey:@"header"];
|
||||
objc_setAssociatedObject(self, &MJRefreshHeaderKey,
|
||||
header,
|
||||
OBJC_ASSOCIATION_ASSIGN);
|
||||
[self didChangeValueForKey:@"header"];
|
||||
|
||||
[self addSubview:header];
|
||||
}
|
||||
}
|
||||
|
||||
- (MJRefreshHeader *)header
|
||||
{
|
||||
return objc_getAssociatedObject(self, &MJRefreshHeaderKey);
|
||||
}
|
||||
|
||||
#pragma mark - 上拉刷新
|
||||
- (MJRefreshLegendFooter *)addLegendFooterWithRefreshingBlock:(void (^)())block
|
||||
{
|
||||
MJRefreshLegendFooter *footer = [self addLegendFooter];
|
||||
footer.refreshingBlock = block;
|
||||
return footer;
|
||||
}
|
||||
|
||||
- (MJRefreshLegendFooter *)addLegendFooterWithRefreshingTarget:(id)target refreshingAction:(SEL)action
|
||||
{
|
||||
MJRefreshLegendFooter *footer = [self addLegendFooter];
|
||||
footer.refreshingTarget = target;
|
||||
footer.refreshingAction = action;
|
||||
return footer;
|
||||
}
|
||||
|
||||
- (MJRefreshLegendFooter *)addLegendFooter
|
||||
{
|
||||
MJRefreshLegendFooter *footer = [[MJRefreshLegendFooter alloc] init];
|
||||
self.footer = footer;
|
||||
|
||||
return footer;
|
||||
}
|
||||
|
||||
- (MJRefreshGifFooter *)addGifFooterWithRefreshingBlock:(void (^)())block
|
||||
{
|
||||
MJRefreshGifFooter *footer = [self addGifFooter];
|
||||
footer.refreshingBlock = block;
|
||||
return footer;
|
||||
}
|
||||
|
||||
- (MJRefreshGifFooter *)addGifFooterWithRefreshingTarget:(id)target refreshingAction:(SEL)action
|
||||
{
|
||||
MJRefreshGifFooter *footer = [self addGifFooter];
|
||||
footer.refreshingTarget = target;
|
||||
footer.refreshingAction = action;
|
||||
return footer;
|
||||
}
|
||||
|
||||
- (MJRefreshGifFooter *)addGifFooter
|
||||
{
|
||||
MJRefreshGifFooter *footer = [[MJRefreshGifFooter alloc] init];
|
||||
self.footer = footer;
|
||||
|
||||
return footer;
|
||||
}
|
||||
|
||||
- (void)removeFooter
|
||||
{
|
||||
self.footer = nil;
|
||||
}
|
||||
|
||||
static char MJRefreshFooterKey;
|
||||
- (void)setFooter:(MJRefreshFooter *)footer
|
||||
{
|
||||
if (footer != self.footer) {
|
||||
[self.footer removeFromSuperview];
|
||||
|
||||
[self willChangeValueForKey:@"footer"];
|
||||
objc_setAssociatedObject(self, &MJRefreshFooterKey,
|
||||
footer,
|
||||
OBJC_ASSOCIATION_ASSIGN);
|
||||
[self didChangeValueForKey:@"footer"];
|
||||
|
||||
[self addSubview:footer];
|
||||
}
|
||||
}
|
||||
|
||||
- (MJRefreshGifFooter *)gifFooter
|
||||
{
|
||||
if ([self.footer isKindOfClass:[MJRefreshGifFooter class]]) {
|
||||
return (MJRefreshGifFooter *)self.footer;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (MJRefreshLegendFooter *)legendFooter
|
||||
{
|
||||
if ([self.footer isKindOfClass:[MJRefreshLegendFooter class]]) {
|
||||
return (MJRefreshLegendFooter *)self.footer;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
- (MJRefreshFooter *)footer
|
||||
{
|
||||
return objc_getAssociatedObject(self, &MJRefreshFooterKey);
|
||||
}
|
||||
|
||||
#pragma mark - swizzle
|
||||
+ (void)load
|
||||
{
|
||||
Method method1 = class_getInstanceMethod([self class], NSSelectorFromString(@"dealloc"));
|
||||
Method method2 = class_getInstanceMethod([self class], @selector(deallocSwizzle));
|
||||
method_exchangeImplementations(method1, method2);
|
||||
}
|
||||
|
||||
- (void)deallocSwizzle
|
||||
{
|
||||
[self removeFooter];
|
||||
[self removeHeader];
|
||||
|
||||
[self deallocSwizzle];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#pragma mark - 1.0.0版本以前的接口
|
||||
@implementation UIScrollView(MJRefreshDeprecated)
|
||||
#pragma mark - 下拉刷新
|
||||
/**
|
||||
* 添加一个下拉刷新头部控件
|
||||
*
|
||||
* @param callback 回调
|
||||
*/
|
||||
- (void)addHeaderWithCallback:(void (^)())callback
|
||||
{
|
||||
[self addHeaderWithCallback:callback dateKey:nil];
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加一个下拉刷新头部控件
|
||||
*
|
||||
* @param callback 回调
|
||||
* @param dateKey 刷新时间保存的key值
|
||||
*/
|
||||
- (void)addHeaderWithCallback:(void (^)())callback dateKey:(NSString*)dateKey
|
||||
{
|
||||
[self addLegendHeader];
|
||||
self.header.dateKey = dateKey;
|
||||
self.header.refreshingBlock = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加一个下拉刷新头部控件
|
||||
*
|
||||
* @param target 目标
|
||||
* @param action 回调方法
|
||||
*/
|
||||
- (void)addHeaderWithTarget:(id)target action:(SEL)action
|
||||
{
|
||||
[self addHeaderWithTarget:target action:action dateKey:nil];
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加一个下拉刷新头部控件
|
||||
*
|
||||
* @param target 目标
|
||||
* @param action 回调方法
|
||||
* @param dateKey 刷新时间保存的key值
|
||||
*/
|
||||
- (void)addHeaderWithTarget:(id)target action:(SEL)action dateKey:(NSString*)dateKey
|
||||
{
|
||||
[self addLegendHeader];
|
||||
self.header.dateKey = dateKey;
|
||||
[self.header setRefreshingTarget:target refreshingAction:action];
|
||||
}
|
||||
|
||||
/**
|
||||
* 主动让下拉刷新头部控件进入刷新状态
|
||||
*/
|
||||
- (void)headerBeginRefreshing
|
||||
{
|
||||
[self.header beginRefreshing];
|
||||
}
|
||||
|
||||
/**
|
||||
* 让下拉刷新头部控件停止刷新状态
|
||||
*/
|
||||
- (void)headerEndRefreshing
|
||||
{
|
||||
[self.header endRefreshing];
|
||||
}
|
||||
|
||||
/**
|
||||
* 下拉刷新头部控件的可见性
|
||||
*/
|
||||
- (void)setHeaderHidden:(BOOL)headerHidden
|
||||
{
|
||||
self.header.hidden = headerHidden;
|
||||
}
|
||||
|
||||
- (BOOL)isHeaderHidden
|
||||
{
|
||||
return self.header.isHidden;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否正在下拉刷新
|
||||
*/
|
||||
- (BOOL)isHeaderRefreshing
|
||||
{
|
||||
return self.header.isRefreshing;
|
||||
}
|
||||
|
||||
#pragma mark - 上拉刷新
|
||||
/**
|
||||
* 添加一个上拉刷新尾部控件
|
||||
*
|
||||
* @param callback 回调
|
||||
*/
|
||||
- (void)addFooterWithCallback:(void (^)())callback
|
||||
{
|
||||
[self addLegendFooter];
|
||||
self.footer.refreshingBlock = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加一个上拉刷新尾部控件
|
||||
*
|
||||
* @param target 目标
|
||||
* @param action 回调方法
|
||||
*/
|
||||
- (void)addFooterWithTarget:(id)target action:(SEL)action
|
||||
{
|
||||
[self addLegendFooter];
|
||||
[self.footer setRefreshingTarget:target refreshingAction:action];
|
||||
}
|
||||
|
||||
/**
|
||||
* 主动让上拉刷新尾部控件进入刷新状态
|
||||
*/
|
||||
- (void)footerBeginRefreshing
|
||||
{
|
||||
[self.footer beginRefreshing];
|
||||
}
|
||||
|
||||
/**
|
||||
* 让上拉刷新尾部控件停止刷新状态
|
||||
*/
|
||||
- (void)footerEndRefreshing
|
||||
{
|
||||
[self.footer endRefreshing];
|
||||
}
|
||||
|
||||
/**
|
||||
* 上拉刷新头部控件的可见性
|
||||
*/
|
||||
- (void)setFooterHidden:(BOOL)footerHidden
|
||||
{
|
||||
self.footer.hidden = footerHidden;
|
||||
}
|
||||
|
||||
- (BOOL)isFooterHidden
|
||||
{
|
||||
return self.footer.isHidden;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否正在上拉刷新
|
||||
*/
|
||||
- (BOOL)isFooterRefreshing
|
||||
{
|
||||
return self.footer.isRefreshing;
|
||||
}
|
||||
@end
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
// 代码地址: https://github.com/CoderMJLee/MJRefresh
|
||||
// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000
|
||||
// UIView+Extension.h
|
||||
// MJRefreshExample
|
||||
//
|
||||
// Created by MJ Lee on 14-5-28.
|
||||
// Copyright (c) 2014年 itcast. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface UIView (MJExtension)
|
||||
@property (assign, nonatomic) CGFloat mj_x;
|
||||
@property (assign, nonatomic) CGFloat mj_y;
|
||||
@property (assign, nonatomic) CGFloat mj_w;
|
||||
@property (assign, nonatomic) CGFloat mj_h;
|
||||
@property (assign, nonatomic) CGSize mj_size;
|
||||
@property (assign, nonatomic) CGPoint mj_origin;
|
||||
@end
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
// 代码地址: https://github.com/CoderMJLee/MJRefresh
|
||||
// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000
|
||||
// UIView+Extension.m
|
||||
// MJRefreshExample
|
||||
//
|
||||
// Created by MJ Lee on 14-5-28.
|
||||
// Copyright (c) 2014年 itcast. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UIView+MJExtension.h"
|
||||
|
||||
@implementation UIView (MJExtension)
|
||||
- (void)setMj_x:(CGFloat)mj_x
|
||||
{
|
||||
CGRect frame = self.frame;
|
||||
frame.origin.x = mj_x;
|
||||
self.frame = frame;
|
||||
}
|
||||
|
||||
- (CGFloat)mj_x
|
||||
{
|
||||
return self.frame.origin.x;
|
||||
}
|
||||
|
||||
- (void)setMj_y:(CGFloat)mj_y
|
||||
{
|
||||
CGRect frame = self.frame;
|
||||
frame.origin.y = mj_y;
|
||||
self.frame = frame;
|
||||
}
|
||||
|
||||
- (CGFloat)mj_y
|
||||
{
|
||||
return self.frame.origin.y;
|
||||
}
|
||||
|
||||
- (void)setMj_w:(CGFloat)mj_w
|
||||
{
|
||||
CGRect frame = self.frame;
|
||||
frame.size.width = mj_w;
|
||||
self.frame = frame;
|
||||
}
|
||||
|
||||
- (CGFloat)mj_w
|
||||
{
|
||||
return self.frame.size.width;
|
||||
}
|
||||
|
||||
- (void)setMj_h:(CGFloat)mj_h
|
||||
{
|
||||
CGRect frame = self.frame;
|
||||
frame.size.height = mj_h;
|
||||
self.frame = frame;
|
||||
}
|
||||
|
||||
- (CGFloat)mj_h
|
||||
{
|
||||
return self.frame.size.height;
|
||||
}
|
||||
|
||||
- (void)setMj_size:(CGSize)mj_size
|
||||
{
|
||||
CGRect frame = self.frame;
|
||||
frame.size = mj_size;
|
||||
self.frame = frame;
|
||||
}
|
||||
|
||||
- (CGSize)mj_size
|
||||
{
|
||||
return self.frame.size;
|
||||
}
|
||||
|
||||
- (void)setMj_origin:(CGPoint)mj_origin
|
||||
{
|
||||
CGRect frame = self.frame;
|
||||
frame.origin = mj_origin;
|
||||
self.frame = frame;
|
||||
}
|
||||
|
||||
- (CGPoint)mj_origin
|
||||
{
|
||||
return self.frame.origin;
|
||||
}
|
||||
@end
|
||||
Reference in New Issue
Block a user