123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- // 代码地址: 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年 小码哥. All rights reserved.
- //
- #import "MJRefreshComponent.h"
- #import "MJRefreshConst.h"
- #import "Aspects.h"
- @interface MJRefreshComponent()
- @property (strong, nonatomic) UIPanGestureRecognizer *pan;
- @end
- @implementation MJRefreshComponent
- #pragma mark - 初始化
- - (instancetype)initWithFrame:(CGRect)frame
- {
- if (self = [super initWithFrame:frame]) {
- // 准备工作
- [self prepare];
-
- // 默认是普通状态
- self.state = MJRefreshStateIdle;
- }
- return self;
- }
- - (void)prepare
- {
- // 基本属性
- self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
- self.backgroundColor = [UIColor clearColor];
- }
- - (void)layoutSubviews
- {
- [self placeSubviews];
-
- [super layoutSubviews];
- }
- - (void)placeSubviews{}
- - (void)willMoveToSuperview:(UIView *)newSuperview
- {
- [super willMoveToSuperview:newSuperview];
-
- // 如果不是UIScrollView,不做任何事情
- if (newSuperview && ![newSuperview isKindOfClass:[UIScrollView class]]) return;
-
- // 旧的父控件移除监听
- [self removeObservers];
-
- if (newSuperview) { // 新的父控件
- // 设置宽度
- self.mj_w = newSuperview.mj_w;
- // 设置位置
- self.mj_x = -_scrollView.mj_insetL;
-
- // 记录UIScrollView
- _scrollView = (UIScrollView *)newSuperview;
- // 设置永远支持垂直弹簧效果
- _scrollView.alwaysBounceVertical = YES;
- // 记录UIScrollView最开始的contentInset
- _scrollViewOriginalInset = _scrollView.mj_inset;
-
- // 添加监听
- [self addObservers];
- }
- }
- - (void)drawRect:(CGRect)rect
- {
- [super drawRect:rect];
-
- if (self.state == MJRefreshStateWillRefresh) {
- // 预防view还没显示出来就调用了beginRefreshing
- self.state = MJRefreshStateRefreshing;
- }
- }
- #pragma mark - KVO监听
- - (void)addObservers
- {
- NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;
- [self.scrollView addObserver:self forKeyPath:MJRefreshKeyPathContentOffset options:options context:nil];
- [self.scrollView addObserver:self forKeyPath:MJRefreshKeyPathContentSize options:options context:nil];
- self.pan = self.scrollView.panGestureRecognizer;
- [self.pan addObserver:self forKeyPath:MJRefreshKeyPathPanState options:options context:nil];
- }
- - (void)removeObservers
- {
- [self.superview removeObserver:self forKeyPath:MJRefreshKeyPathContentOffset];
- [self.superview removeObserver:self forKeyPath:MJRefreshKeyPathContentSize];
- [self.pan removeObserver:self forKeyPath:MJRefreshKeyPathPanState];
- self.pan = nil;
- }
- - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
- {
- // 遇到这些情况就直接返回
- if (!self.userInteractionEnabled) return;
-
- // 这个就算看不见也需要处理
- if ([keyPath isEqualToString:MJRefreshKeyPathContentSize]) {
- [self scrollViewContentSizeDidChange:change];
- }
-
- // 看不见
- if (self.hidden) return;
- if ([keyPath isEqualToString:MJRefreshKeyPathContentOffset]) {
- [self scrollViewContentOffsetDidChange:change];
- } else if ([keyPath isEqualToString:MJRefreshKeyPathPanState]) {
- [self scrollViewPanStateDidChange:change];
- }
- }
- - (void)scrollViewContentOffsetDidChange:(NSDictionary *)change{}
- - (void)scrollViewContentSizeDidChange:(NSDictionary *)change{}
- - (void)scrollViewPanStateDidChange:(NSDictionary *)change{}
- #pragma mark - 公共方法
- #pragma mark 设置回调对象和回调方法
- - (void)setRefreshingTarget:(id)target refreshingAction:(SEL)action
- {
- self.refreshingTarget = target;
- self.refreshingAction = action;
- }
- - (void)setState:(MJRefreshState)state
- {
- _state = state;
-
- // 加入主队列的目的是等setState:方法调用完毕、设置完文字后再去布局子控件
- MJRefreshDispatchAsyncOnMainQueue([self setNeedsLayout];)
- }
- #pragma mark 进入刷新状态
- - (void)beginRefreshing
- {
- [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{
- self.alpha = 1.0;
- }];
- self.pullingPercent = 1.0;
- // 只要正在刷新,就完全显示
- if (self.window) {
- self.state = MJRefreshStateRefreshing;
- } else {
- // 预防正在刷新中时,调用本方法使得header inset回置失败
- if (self.state != MJRefreshStateRefreshing) {
- self.state = MJRefreshStateWillRefresh;
- // 刷新(预防从另一个控制器回到这个控制器的情况,回来要重新刷新一下)
- [self setNeedsDisplay];
- }
- }
- }
- - (void)beginRefreshingWithCompletionBlock:(void (^)(void))completionBlock
- {
- self.beginRefreshingCompletionBlock = completionBlock;
-
- [self beginRefreshing];
- }
- #pragma mark 结束刷新状态
- - (void)endRefreshing
- {
- MJRefreshDispatchAsyncOnMainQueue(self.state = MJRefreshStateIdle;)
- }
- - (void)endRefreshingWithCompletionBlock:(void (^)(void))completionBlock
- {
- self.endRefreshingCompletionBlock = completionBlock;
-
- [self endRefreshing];
- }
- /// <#Description#>
- -(void)aspectsEndRefreshing:(void (^)(void))block{
- [self aspect_hookSelector:@selector(endRefreshing) withOptions:AspectPositionAfter usingBlock:block error:nil];
- [self aspect_hookSelector:@selector(endRefreshingCompletionBlock) withOptions:AspectPositionAfter usingBlock:block error:nil];
- }
- #pragma mark 是否正在刷新
- - (BOOL)isRefreshing
- {
- return self.state == MJRefreshStateRefreshing || self.state == MJRefreshStateWillRefresh;
- }
- #pragma mark 自动切换透明度
- - (void)setAutoChangeAlpha:(BOOL)autoChangeAlpha
- {
- self.automaticallyChangeAlpha = autoChangeAlpha;
- }
- - (BOOL)isAutoChangeAlpha
- {
- return self.isAutomaticallyChangeAlpha;
- }
- - (void)setAutomaticallyChangeAlpha:(BOOL)automaticallyChangeAlpha
- {
- _automaticallyChangeAlpha = automaticallyChangeAlpha;
-
- if (self.isRefreshing) return;
-
- if (automaticallyChangeAlpha) {
- self.alpha = self.pullingPercent;
- } else {
- self.alpha = 1.0;
- }
- }
- #pragma mark 根据拖拽进度设置透明度
- - (void)setPullingPercent:(CGFloat)pullingPercent
- {
- _pullingPercent = pullingPercent;
-
- if (self.isRefreshing) return;
-
- if (self.isAutomaticallyChangeAlpha) {
- self.alpha = pullingPercent;
- }
- }
- #pragma mark - 内部方法
- - (void)executeRefreshingCallback
- {
- MJRefreshDispatchAsyncOnMainQueue({
- if (self.refreshingBlock) {
- self.refreshingBlock();
- }
- if ([self.refreshingTarget respondsToSelector:self.refreshingAction]) {
- MJRefreshMsgSend(MJRefreshMsgTarget(self.refreshingTarget), self.refreshingAction, self);
- }
- if (self.beginRefreshingCompletionBlock) {
- self.beginRefreshingCompletionBlock();
- }
- })
- }
- @end
- @implementation UILabel(MJRefresh)
- + (instancetype)mj_label
- {
- UILabel *label = [[self alloc] init];
- label.font = MJRefreshLabelFont;
- label.textColor = MJRefreshLabelTextColor;
- label.autoresizingMask = UIViewAutoresizingFlexibleWidth;
- label.textAlignment = NSTextAlignmentCenter;
- label.backgroundColor = [UIColor clearColor];
- return label;
- }
- - (CGFloat)mj_textWith {
- CGFloat stringWidth = 0;
- CGSize size = CGSizeMake(MAXFLOAT, MAXFLOAT);
- if (self.text.length > 0) {
- #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
- stringWidth =[self.text
- boundingRectWithSize:size
- options:NSStringDrawingUsesLineFragmentOrigin
- attributes:@{NSFontAttributeName:self.font}
- context:nil].size.width;
- #else
-
- stringWidth = [self.text sizeWithFont:self.font
- constrainedToSize:size
- lineBreakMode:NSLineBreakByCharWrapping].width;
- #endif
- }
- return stringWidth;
- }
- @end
|