Commit 33c9d396 authored by jz's avatar jz

替换为最新MJRe

parent 8e66581b
...@@ -213,7 +213,6 @@ ...@@ -213,7 +213,6 @@
6003F587195388D20070C39A /* Frameworks */, 6003F587195388D20070C39A /* Frameworks */,
6003F588195388D20070C39A /* Resources */, 6003F588195388D20070C39A /* Resources */,
88C96FFAE5ACFCA8DAE2E535 /* [CP] Embed Pods Frameworks */, 88C96FFAE5ACFCA8DAE2E535 /* [CP] Embed Pods Frameworks */,
AC731551ACD6686FC4DB21B0 /* [CP] Copy Pods Resources */,
); );
buildRules = ( buildRules = (
); );
...@@ -232,8 +231,6 @@ ...@@ -232,8 +231,6 @@
6003F5AA195388D20070C39A /* Sources */, 6003F5AA195388D20070C39A /* Sources */,
6003F5AB195388D20070C39A /* Frameworks */, 6003F5AB195388D20070C39A /* Frameworks */,
6003F5AC195388D20070C39A /* Resources */, 6003F5AC195388D20070C39A /* Resources */,
AC94AF4168D3DD1E67AAB021 /* [CP] Embed Pods Frameworks */,
B24157C697F0666FDF323615 /* [CP] Copy Pods Resources */,
); );
buildRules = ( buildRules = (
); );
...@@ -326,7 +323,7 @@ ...@@ -326,7 +323,7 @@
files = ( files = (
); );
inputPaths = ( inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-GMRefresh_Example/Pods-GMRefresh_Example-frameworks.sh", "${PODS_ROOT}/Target Support Files/Pods-GMRefresh_Example/Pods-GMRefresh_Example-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/GMCache/GMCache.framework", "${BUILT_PRODUCTS_DIR}/GMCache/GMCache.framework",
"${BUILT_PRODUCTS_DIR}/GMKit/GMKit.framework", "${BUILT_PRODUCTS_DIR}/GMKit/GMKit.framework",
"${BUILT_PRODUCTS_DIR}/GMPhobos/GMPhobos.framework", "${BUILT_PRODUCTS_DIR}/GMPhobos/GMPhobos.framework",
...@@ -347,52 +344,7 @@ ...@@ -347,52 +344,7 @@
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-GMRefresh_Example/Pods-GMRefresh_Example-frameworks.sh\"\n"; shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-GMRefresh_Example/Pods-GMRefresh_Example-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
AC731551ACD6686FC4DB21B0 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-GMRefresh_Example/Pods-GMRefresh_Example-resources.sh\"\n";
showEnvVarsInLog = 0;
};
AC94AF4168D3DD1E67AAB021 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-GMRefresh_Tests/Pods-GMRefresh_Tests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
B24157C697F0666FDF323615 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-GMRefresh_Tests/Pods-GMRefresh_Tests-resources.sh\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
BD53463213654FBF55212ABA /* [CP] Check Pods Manifest.lock */ = { BD53463213654FBF55212ABA /* [CP] Check Pods Manifest.lock */ = {
......
PODS: PODS:
- GMCache (0.1.1): - GMCache (1.0.1):
- TMCache (~> 2.1.0) - TMCache (= 2.1.0)
- GMKit (0.7.41): - GMKit (1.1.4):
- GMKit/Category (= 0.7.41) - GMKit/Category (= 1.1.4)
- GMKit/Color (= 0.7.41) - GMKit/Color (= 1.1.4)
- GMKit/Constant (= 0.7.41) - GMKit/Constant (= 1.1.4)
- GMKit/FDFullscreenPopGesture (= 0.7.41) - GMKit/FDFullscreenPopGesture (= 1.1.4)
- GMKit/Kit (= 0.7.41) - GMKit/Kit (= 1.1.4)
- GMKit/Protocol (= 0.7.41) - GMKit/Protocol (= 1.1.4)
- Masonry (= 1.1.0) - Masonry
- SDWebImage (= 3.7.6) - SDWebImage
- GMKit/Category (0.7.41): - GMKit/Category (1.1.4):
- GMKit/Color (= 0.7.41) - GMKit/Color (= 1.1.4)
- GMKit/Constant (= 0.7.41) - GMKit/Constant (= 1.1.4)
- GMKit/Protocol (= 0.7.41) - GMKit/Protocol (= 1.1.4)
- Masonry (= 1.1.0) - Masonry
- SDWebImage (= 3.7.6) - SDWebImage
- GMKit/Color (0.7.41): - GMKit/Color (1.1.4):
- Masonry (= 1.1.0) - Masonry
- SDWebImage (= 3.7.6) - SDWebImage
- GMKit/Constant (0.7.41): - GMKit/Constant (1.1.4):
- Masonry (= 1.1.0) - Masonry
- SDWebImage (= 3.7.6) - SDWebImage
- GMKit/FDFullscreenPopGesture (0.7.41): - GMKit/FDFullscreenPopGesture (1.1.4):
- Masonry (= 1.1.0) - Masonry
- SDWebImage (= 3.7.6) - SDWebImage
- GMKit/Kit (0.7.41): - GMKit/Kit (1.1.4):
- GMKit/Category (= 0.7.41) - GMKit/Category (= 1.1.4)
- GMKit/Color (= 0.7.41) - GMKit/Color (= 1.1.4)
- GMKit/Constant (= 0.7.41) - GMKit/Constant (= 1.1.4)
- GMKit/Protocol (= 0.7.41) - GMKit/Protocol (= 1.1.4)
- Masonry (= 1.1.0) - Masonry
- SDWebImage (= 3.7.6) - SDWebImage
- GMKit/Protocol (0.7.41): - GMKit/Protocol (1.1.4):
- Masonry (= 1.1.0) - Masonry
- SDWebImage (= 3.7.6) - SDWebImage
- GMPhobos (0.4.6): - GMPhobos (1.3.4):
- GMCache (~> 0.1.1) - GMCache
- GMKit - GMKit
- GMRefresh (0.1.81): - GMRefresh (1.0.3):
- GMPhobos - GMPhobos
- Masonry (1.1.0) - Masonry (1.1.0)
- SDWebImage (3.7.6): - SDWebImage (5.3.1):
- SDWebImage/Core (= 3.7.6) - SDWebImage/Core (= 5.3.1)
- SDWebImage/Core (3.7.6) - SDWebImage/Core (5.3.1)
- TMCache (2.1.0) - TMCache (2.1.0)
DEPENDENCIES: DEPENDENCIES:
- GMRefresh (from `../`) - GMRefresh (from `../`)
SPEC REPOS:
"git@git.wanmeizhensuo.com:gengmeiios/GMSpecs.git":
- GMCache
- GMKit
- GMPhobos
https://github.com/cocoapods/specs.git:
- Masonry
- SDWebImage
- TMCache
EXTERNAL SOURCES: EXTERNAL SOURCES:
GMRefresh: GMRefresh:
:path: ../ :path: "../"
SPEC CHECKSUMS: SPEC CHECKSUMS:
GMCache: 73855b613b9d7e34f4f37ad425e8b8153b760c04 GMCache: b78d8e46db864405e91d226ce640cc80d966c611
GMKit: 4820e0eb7727735f88fb2f983f178edd074343c1 GMKit: 11c9ab9a317f381a05b0e1e577dd95a495625edf
GMPhobos: 4a6dcf21fe2e1f81ac7761217bff1a92655dc88c GMPhobos: 6c7ae144997ace1661fe315adcc78c394cb73291
GMRefresh: d818f36645fb714ae54292e18ce7e0cb6d5c2a1c GMRefresh: 16d96e530312cd5b26a21c939437fa88829dad54
Masonry: 678fab65091a9290e40e2832a55e7ab731aad201 Masonry: 678fab65091a9290e40e2832a55e7ab731aad201
SDWebImage: c325cf02c30337336b95beff20a13df489ec0ec9 SDWebImage: 7137d57385fb632129838c1e6ab9528a22c666cc
TMCache: 95ebcc9b3c7e90fb5fd8fc3036cba3aa781c9bed TMCache: 95ebcc9b3c7e90fb5fd8fc3036cba3aa781c9bed
PODFILE CHECKSUM: a967856f0f3fe38865db489c22abaf1fecccf026 PODFILE CHECKSUM: a967856f0f3fe38865db489c22abaf1fecccf026
COCOAPODS: 1.3.1 COCOAPODS: 1.7.4
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#import "MJRefreshFooter.h" #import "MJRefreshFooter.h"
NS_ASSUME_NONNULL_BEGIN
@interface MJRefreshAutoFooter : MJRefreshFooter @interface MJRefreshAutoFooter : MJRefreshFooter
/** 是否自动刷新(默认为YES) */ /** 是否自动刷新(默认为YES) */
@property (assign, nonatomic, getter=isAutomaticallyRefresh) BOOL automaticallyRefresh; @property (assign, nonatomic, getter=isAutomaticallyRefresh) BOOL automaticallyRefresh;
...@@ -17,4 +19,12 @@ ...@@ -17,4 +19,12 @@
/** 当底部控件出现多少时就自动刷新(默认为1.0,也就是底部控件完全出现时,才会自动刷新) */ /** 当底部控件出现多少时就自动刷新(默认为1.0,也就是底部控件完全出现时,才会自动刷新) */
@property (assign, nonatomic) CGFloat triggerAutomaticallyRefreshPercent; @property (assign, nonatomic) CGFloat triggerAutomaticallyRefreshPercent;
/** 是否每一次拖拽只发一次请求 */
@property (assign, nonatomic, getter=isOnlyRefreshPerDrag) BOOL onlyRefreshPerDrag;
/** 在触发开始刷新前的刷新忽略逻辑, 默认由 isOnlyRefreshPerDrag 和 新手势决定, 用于特殊控制逻辑, 如果不清楚机制, 请勿使用 */
- (BOOL)ignoreRefreshAction NS_REQUIRES_SUPER;
@end @end
NS_ASSUME_NONNULL_END
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#import "MJRefreshAutoFooter.h" #import "MJRefreshAutoFooter.h"
@interface MJRefreshAutoFooter() @interface MJRefreshAutoFooter()
/** 一个新的拖拽 */
@property (assign, nonatomic, getter=isOneNewPan) BOOL oneNewPan;
@end @end
@implementation MJRefreshAutoFooter @implementation MJRefreshAutoFooter
...@@ -53,6 +55,9 @@ ...@@ -53,6 +55,9 @@
// 设置为默认状态 // 设置为默认状态
self.automaticallyRefresh = YES; self.automaticallyRefresh = YES;
// 默认是当offset达到条件就发送请求(可连续)
self.onlyRefreshPerDrag = YES;
} }
- (void)scrollViewContentSizeDidChange:(NSDictionary *)change - (void)scrollViewContentSizeDidChange:(NSDictionary *)change
...@@ -60,7 +65,7 @@ ...@@ -60,7 +65,7 @@
[super scrollViewContentSizeDidChange:change]; [super scrollViewContentSizeDidChange:change];
// 设置位置 // 设置位置
self.mj_y = self.scrollView.mj_contentH; self.mj_y = self.scrollView.mj_contentH + self.ignoredScrollViewContentInsetBottom;
} }
- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change - (void)scrollViewContentOffsetDidChange:(NSDictionary *)change
...@@ -89,7 +94,11 @@ ...@@ -89,7 +94,11 @@
if (self.state != MJRefreshStateIdle) return; if (self.state != MJRefreshStateIdle) return;
if (_scrollView.panGestureRecognizer.state == UIGestureRecognizerStateEnded) {// 手松开 UIGestureRecognizerState panState = _scrollView.panGestureRecognizer.state;
switch (panState) {
// 手松开
case UIGestureRecognizerStateEnded: {
if (_scrollView.mj_insetT + _scrollView.mj_contentH <= _scrollView.mj_h) { // 不够一个屏幕 if (_scrollView.mj_insetT + _scrollView.mj_contentH <= _scrollView.mj_h) { // 不够一个屏幕
if (_scrollView.mj_offsetY >= - _scrollView.mj_insetT) { // 向上拽 if (_scrollView.mj_offsetY >= - _scrollView.mj_insetT) { // 向上拽
[self beginRefreshing]; [self beginRefreshing];
...@@ -99,17 +108,41 @@ ...@@ -99,17 +108,41 @@
[self beginRefreshing]; [self beginRefreshing];
} }
} }
}// ‼️注意: 这里没有 break; fallthrough 执行重置 oneNewPan 语句 (Ended & Canceled & Failed)
case UIGestureRecognizerStateCancelled:
case UIGestureRecognizerStateFailed: {
self.oneNewPan = NO;
}
break;
case UIGestureRecognizerStateBegan: {
self.oneNewPan = YES;
}
break;
default:
break;
} }
} }
- (BOOL)ignoreRefreshAction {
return !self.isOneNewPan && self.isOnlyRefreshPerDrag;
}
- (void)beginRefreshing
{
if ([self ignoreRefreshAction]) return;
[super beginRefreshing];
}
- (void)setState:(MJRefreshState)state - (void)setState:(MJRefreshState)state
{ {
MJRefreshCheckState MJRefreshCheckState
if (state == MJRefreshStateRefreshing) { if (state == MJRefreshStateRefreshing) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self executeRefreshingCallback]; [self executeRefreshingCallback];
});
} else if (state == MJRefreshStateNoMoreData || state == MJRefreshStateIdle) { } else if (state == MJRefreshStateNoMoreData || state == MJRefreshStateIdle) {
if (MJRefreshStateRefreshing == oldState) { if (MJRefreshStateRefreshing == oldState) {
if (self.endRefreshingCompletionBlock) { if (self.endRefreshingCompletionBlock) {
......
...@@ -8,6 +8,10 @@ ...@@ -8,6 +8,10 @@
#import "MJRefreshFooter.h" #import "MJRefreshFooter.h"
NS_ASSUME_NONNULL_BEGIN
@interface MJRefreshBackFooter : MJRefreshFooter @interface MJRefreshBackFooter : MJRefreshFooter
@end @end
NS_ASSUME_NONNULL_END
...@@ -91,6 +91,9 @@ ...@@ -91,6 +91,9 @@
[UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{ [UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{
self.scrollView.mj_insetB -= self.lastBottomDelta; self.scrollView.mj_insetB -= self.lastBottomDelta;
if (self.endRefreshingAnimateCompletionBlock) {
self.endRefreshingAnimateCompletionBlock();
}
// 自动调整透明度 // 自动调整透明度
if (self.isAutomaticallyChangeAlpha) self.alpha = 0.0; if (self.isAutomaticallyChangeAlpha) self.alpha = 0.0;
} completion:^(BOOL finished) { } completion:^(BOOL finished) {
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#import "UIScrollView+MJRefresh.h" #import "UIScrollView+MJRefresh.h"
#import "NSBundle+MJRefresh.h" #import "NSBundle+MJRefresh.h"
NS_ASSUME_NONNULL_BEGIN
/** 刷新控件的状态 */ /** 刷新控件的状态 */
typedef NS_ENUM(NSInteger, MJRefreshState) { typedef NS_ENUM(NSInteger, MJRefreshState) {
/** 普通闲置状态 */ /** 普通闲置状态 */
...@@ -31,7 +33,7 @@ typedef NS_ENUM(NSInteger, MJRefreshState) { ...@@ -31,7 +33,7 @@ typedef NS_ENUM(NSInteger, MJRefreshState) {
/** 进入刷新状态的回调 */ /** 进入刷新状态的回调 */
typedef void (^MJRefreshComponentRefreshingBlock)(void); typedef void (^MJRefreshComponentRefreshingBlock)(void);
/** 开始刷新后的回调(进入刷新状态后的回调) */ /** 开始刷新后的回调(进入刷新状态后的回调) */
typedef void (^MJRefreshComponentbeginRefreshingCompletionBlock)(void); typedef void (^MJRefreshComponentBeginRefreshingCompletionBlock)(void);
/** 结束刷新后的回调 */ /** 结束刷新后的回调 */
typedef void (^MJRefreshComponentEndRefreshingCompletionBlock)(void); typedef void (^MJRefreshComponentEndRefreshingCompletionBlock)(void);
...@@ -45,7 +47,7 @@ typedef void (^MJRefreshComponentEndRefreshingCompletionBlock)(void); ...@@ -45,7 +47,7 @@ typedef void (^MJRefreshComponentEndRefreshingCompletionBlock)(void);
} }
#pragma mark - 刷新回调 #pragma mark - 刷新回调
/** 正在刷新的回调 */ /** 正在刷新的回调 */
@property (copy, nonatomic) MJRefreshComponentRefreshingBlock refreshingBlock; @property (copy, nonatomic, nullable) MJRefreshComponentRefreshingBlock refreshingBlock;
/** 设置回调对象和回调方法 */ /** 设置回调对象和回调方法 */
- (void)setRefreshingTarget:(id)target refreshingAction:(SEL)action; - (void)setRefreshingTarget:(id)target refreshingAction:(SEL)action;
...@@ -61,15 +63,17 @@ typedef void (^MJRefreshComponentEndRefreshingCompletionBlock)(void); ...@@ -61,15 +63,17 @@ typedef void (^MJRefreshComponentEndRefreshingCompletionBlock)(void);
- (void)beginRefreshing; - (void)beginRefreshing;
- (void)beginRefreshingWithCompletionBlock:(void (^)(void))completionBlock; - (void)beginRefreshingWithCompletionBlock:(void (^)(void))completionBlock;
/** 开始刷新后的回调(进入刷新状态后的回调) */ /** 开始刷新后的回调(进入刷新状态后的回调) */
@property (copy, nonatomic) MJRefreshComponentbeginRefreshingCompletionBlock beginRefreshingCompletionBlock; @property (copy, nonatomic, nullable) MJRefreshComponentBeginRefreshingCompletionBlock beginRefreshingCompletionBlock;
/** 带动画的结束刷新的回调 */
@property (copy, nonatomic, nullable) MJRefreshComponentEndRefreshingCompletionBlock endRefreshingAnimateCompletionBlock;
/** 结束刷新的回调 */ /** 结束刷新的回调 */
@property (copy, nonatomic) MJRefreshComponentEndRefreshingCompletionBlock endRefreshingCompletionBlock; @property (copy, nonatomic, nullable) MJRefreshComponentEndRefreshingCompletionBlock endRefreshingCompletionBlock;
/** 结束刷新状态 */ /** 结束刷新状态 */
- (void)endRefreshing; - (void)endRefreshing;
- (void)endRefreshingWithCompletionBlock:(void (^)(void))completionBlock; - (void)endRefreshingWithCompletionBlock:(void (^)(void))completionBlock;
/** 是否正在刷新 */ /** 是否正在刷新 */
@property (assign, nonatomic, readonly, getter=isRefreshing) BOOL refreshing; @property (assign, nonatomic, readonly, getter=isRefreshing) BOOL refreshing;
//- (BOOL)isRefreshing;
/** 刷新状态 一般交给子类内部实现 */ /** 刷新状态 一般交给子类内部实现 */
@property (assign, nonatomic) MJRefreshState state; @property (assign, nonatomic) MJRefreshState state;
...@@ -85,11 +89,11 @@ typedef void (^MJRefreshComponentEndRefreshingCompletionBlock)(void); ...@@ -85,11 +89,11 @@ typedef void (^MJRefreshComponentEndRefreshingCompletionBlock)(void);
/** 摆放子控件frame */ /** 摆放子控件frame */
- (void)placeSubviews NS_REQUIRES_SUPER; - (void)placeSubviews NS_REQUIRES_SUPER;
/** 当scrollView的contentOffset发生改变的时候调用 */ /** 当scrollView的contentOffset发生改变的时候调用 */
- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change NS_REQUIRES_SUPER; - (void)scrollViewContentOffsetDidChange:(nullable NSDictionary *)change NS_REQUIRES_SUPER;
/** 当scrollView的contentSize发生改变的时候调用 */ /** 当scrollView的contentSize发生改变的时候调用 */
- (void)scrollViewContentSizeDidChange:(NSDictionary *)change NS_REQUIRES_SUPER; - (void)scrollViewContentSizeDidChange:(nullable NSDictionary *)change NS_REQUIRES_SUPER;
/** 当scrollView的拖拽状态发生改变的时候调用 */ /** 当scrollView的拖拽状态发生改变的时候调用 */
- (void)scrollViewPanStateDidChange:(NSDictionary *)change NS_REQUIRES_SUPER; - (void)scrollViewPanStateDidChange:(nullable NSDictionary *)change NS_REQUIRES_SUPER;
#pragma mark - 其他 #pragma mark - 其他
...@@ -103,5 +107,8 @@ typedef void (^MJRefreshComponentEndRefreshingCompletionBlock)(void); ...@@ -103,5 +107,8 @@ typedef void (^MJRefreshComponentEndRefreshingCompletionBlock)(void);
@interface UILabel(MJRefresh) @interface UILabel(MJRefresh)
+ (instancetype)mj_label; + (instancetype)mj_label;
- (CGFloat)mj_textWith; - (CGFloat)mj_textWidth;
@end @end
NS_ASSUME_NONNULL_END
...@@ -55,13 +55,14 @@ ...@@ -55,13 +55,14 @@
[self removeObservers]; [self removeObservers];
if (newSuperview) { // 新的父控件 if (newSuperview) { // 新的父控件
// 记录UIScrollView
_scrollView = (UIScrollView *)newSuperview;
// 设置宽度 // 设置宽度
self.mj_w = newSuperview.mj_w; self.mj_w = _scrollView.mj_w;
// 设置位置 // 设置位置
self.mj_x = -_scrollView.mj_insetL; self.mj_x = -_scrollView.mj_insetL;
// 记录UIScrollView
_scrollView = (UIScrollView *)newSuperview;
// 设置永远支持垂直弹簧效果 // 设置永远支持垂直弹簧效果
_scrollView.alwaysBounceVertical = YES; _scrollView.alwaysBounceVertical = YES;
// 记录UIScrollView最开始的contentInset // 记录UIScrollView最开始的contentInset
...@@ -136,9 +137,7 @@ ...@@ -136,9 +137,7 @@
_state = state; _state = state;
// 加入主队列的目的是等setState:方法调用完毕、设置完文字后再去布局子控件 // 加入主队列的目的是等setState:方法调用完毕、设置完文字后再去布局子控件
dispatch_async(dispatch_get_main_queue(), ^{ MJRefreshDispatchAsyncOnMainQueue([self setNeedsLayout];)
[self setNeedsLayout];
});
} }
#pragma mark 进入刷新状态 #pragma mark 进入刷新状态
...@@ -171,9 +170,7 @@ ...@@ -171,9 +170,7 @@
#pragma mark 结束刷新状态 #pragma mark 结束刷新状态
- (void)endRefreshing - (void)endRefreshing
{ {
dispatch_async(dispatch_get_main_queue(), ^{ MJRefreshDispatchAsyncOnMainQueue(self.state = MJRefreshStateIdle;)
self.state = MJRefreshStateIdle;
});
} }
- (void)endRefreshingWithCompletionBlock:(void (^)(void))completionBlock - (void)endRefreshingWithCompletionBlock:(void (^)(void))completionBlock
...@@ -228,7 +225,7 @@ ...@@ -228,7 +225,7 @@
#pragma mark - 内部方法 #pragma mark - 内部方法
- (void)executeRefreshingCallback - (void)executeRefreshingCallback
{ {
dispatch_async(dispatch_get_main_queue(), ^{ MJRefreshDispatchAsyncOnMainQueue({
if (self.refreshingBlock) { if (self.refreshingBlock) {
self.refreshingBlock(); self.refreshingBlock();
} }
...@@ -238,7 +235,7 @@ ...@@ -238,7 +235,7 @@
if (self.beginRefreshingCompletionBlock) { if (self.beginRefreshingCompletionBlock) {
self.beginRefreshingCompletionBlock(); self.beginRefreshingCompletionBlock();
} }
}); })
} }
@end @end
...@@ -254,22 +251,14 @@ ...@@ -254,22 +251,14 @@
return label; return label;
} }
- (CGFloat)mj_textWith { - (CGFloat)mj_textWidth {
CGFloat stringWidth = 0; CGFloat stringWidth = 0;
CGSize size = CGSizeMake(MAXFLOAT, MAXFLOAT); CGSize size = CGSizeMake(MAXFLOAT, MAXFLOAT);
if (self.text.length > 0) { if (self.text.length > 0) {
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 stringWidth = [self.text boundingRectWithSize:size
stringWidth =[self.text
boundingRectWithSize:size
options:NSStringDrawingUsesLineFragmentOrigin options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName:self.font} attributes:@{NSFontAttributeName:self.font}
context:nil].size.width; context:nil].size.width;
#else
stringWidth = [self.text sizeWithFont:self.font
constrainedToSize:size
lineBreakMode:NSLineBreakByCharWrapping].width;
#endif
} }
return stringWidth; return stringWidth;
} }
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#import "MJRefreshComponent.h" #import "MJRefreshComponent.h"
NS_ASSUME_NONNULL_BEGIN
@interface MJRefreshFooter : MJRefreshComponent @interface MJRefreshFooter : MJRefreshComponent
/** 创建footer */ /** 创建footer */
+ (instancetype)footerWithRefreshingBlock:(MJRefreshComponentRefreshingBlock)refreshingBlock; + (instancetype)footerWithRefreshingBlock:(MJRefreshComponentRefreshingBlock)refreshingBlock;
...@@ -26,5 +28,7 @@ ...@@ -26,5 +28,7 @@
@property (assign, nonatomic) CGFloat ignoredScrollViewContentInsetBottom; @property (assign, nonatomic) CGFloat ignoredScrollViewContentInsetBottom;
/** 自动根据有无数据来显示和隐藏(有数据就显示,没有数据隐藏。默认是NO) */ /** 自动根据有无数据来显示和隐藏(有数据就显示,没有数据隐藏。默认是NO) */
@property (assign, nonatomic, getter=isAutomaticallyHidden) BOOL automaticallyHidden; @property (assign, nonatomic, getter=isAutomaticallyHidden) BOOL automaticallyHidden MJRefreshDeprecated("已废弃此属性,开发者请自行控制footer的显示和隐藏");
@end @end
NS_ASSUME_NONNULL_END
...@@ -38,31 +38,13 @@ ...@@ -38,31 +38,13 @@
self.mj_h = MJRefreshFooterHeight; self.mj_h = MJRefreshFooterHeight;
// 默认不会自动隐藏 // 默认不会自动隐藏
self.automaticallyHidden = NO; // self.automaticallyHidden = NO;
}
- (void)willMoveToSuperview:(UIView *)newSuperview
{
[super willMoveToSuperview:newSuperview];
if (newSuperview) {
// 监听scrollView数据的变化
if ([self.scrollView isKindOfClass:[UITableView class]] || [self.scrollView isKindOfClass:[UICollectionView class]]) {
[self.scrollView setMj_reloadDataBlock:^(NSInteger totalDataCount) {
if (self.isAutomaticallyHidden) {
self.hidden = (totalDataCount == 0);
}
}];
}
}
} }
#pragma mark - 公共方法 #pragma mark - 公共方法
- (void)endRefreshingWithNoMoreData - (void)endRefreshingWithNoMoreData
{ {
dispatch_async(dispatch_get_main_queue(), ^{ MJRefreshDispatchAsyncOnMainQueue(self.state = MJRefreshStateNoMoreData;)
self.state = MJRefreshStateNoMoreData;
});
} }
- (void)noticeNoMoreData - (void)noticeNoMoreData
...@@ -72,24 +54,11 @@ ...@@ -72,24 +54,11 @@
- (void)resetNoMoreData - (void)resetNoMoreData
{ {
dispatch_async(dispatch_get_main_queue(), ^{ MJRefreshDispatchAsyncOnMainQueue(self.state = MJRefreshStateIdle;)
self.state = MJRefreshStateIdle;
});
} }
- (void)setAutomaticallyHidden:(BOOL)automaticallyHidden - (void)setAutomaticallyHidden:(BOOL)automaticallyHidden
{ {
_automaticallyHidden = automaticallyHidden; _automaticallyHidden = automaticallyHidden;
if (automaticallyHidden) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[UITableView exchangeInstanceMethod1:@selector(reloadData) method2:@selector(mj_reloadData)];
[UICollectionView exchangeInstanceMethod1:@selector(reloadData) method2:@selector(mj_reloadData)];
});
#pragma clang diagnostic pop
}
} }
@end @end
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#import "MJRefreshComponent.h" #import "MJRefreshComponent.h"
NS_ASSUME_NONNULL_BEGIN
@interface MJRefreshHeader : MJRefreshComponent @interface MJRefreshHeader : MJRefreshComponent
/** 创建header */ /** 创建header */
+ (instancetype)headerWithRefreshingBlock:(MJRefreshComponentRefreshingBlock)refreshingBlock; + (instancetype)headerWithRefreshingBlock:(MJRefreshComponentRefreshingBlock)refreshingBlock;
...@@ -18,8 +20,10 @@ ...@@ -18,8 +20,10 @@
/** 这个key用来存储上一次下拉刷新成功的时间 */ /** 这个key用来存储上一次下拉刷新成功的时间 */
@property (copy, nonatomic) NSString *lastUpdatedTimeKey; @property (copy, nonatomic) NSString *lastUpdatedTimeKey;
/** 上一次下拉刷新成功的时间 */ /** 上一次下拉刷新成功的时间 */
@property (strong, nonatomic, readonly) NSDate *lastUpdatedTime; @property (strong, nonatomic, readonly, nullable) NSDate *lastUpdatedTime;
/** 忽略多少scrollView的contentInset的top */ /** 忽略多少scrollView的contentInset的top */
@property (assign, nonatomic) CGFloat ignoredScrollViewContentInsetTop; @property (assign, nonatomic) CGFloat ignoredScrollViewContentInsetTop;
@end @end
NS_ASSUME_NONNULL_END
...@@ -48,20 +48,31 @@ ...@@ -48,20 +48,31 @@
self.mj_y = - self.mj_h - self.ignoredScrollViewContentInsetTop; self.mj_y = - self.mj_h - self.ignoredScrollViewContentInsetTop;
} }
- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change - (void)resetInset {
{ if (@available(iOS 11.0, *)) {
[super scrollViewContentOffsetDidChange:change]; } else {
// 如果 iOS 10 及以下系统在刷新时, push 新的 VC, 等待刷新完成后回来, 会导致顶部 Insets.top 异常, 不能 resetInset, 检查一下这种特殊情况
// 在刷新的refreshing状态 if (!self.window) { return; }
if (self.state == MJRefreshStateRefreshing) { }
// if (self.window == nil) return;
// sectionheader停留解决 // sectionheader停留解决
CGFloat insetT = - self.scrollView.mj_offsetY > _scrollViewOriginalInset.top ? - self.scrollView.mj_offsetY : _scrollViewOriginalInset.top; CGFloat insetT = - self.scrollView.mj_offsetY > _scrollViewOriginalInset.top ? - self.scrollView.mj_offsetY : _scrollViewOriginalInset.top;
insetT = insetT > self.mj_h + _scrollViewOriginalInset.top ? self.mj_h + _scrollViewOriginalInset.top : insetT; insetT = insetT > self.mj_h + _scrollViewOriginalInset.top ? self.mj_h + _scrollViewOriginalInset.top : insetT;
self.insetTDelta = _scrollViewOriginalInset.top - insetT;
// 避免 CollectionView 在使用根据 Autolayout 和 内容自动伸缩 Cell, 刷新时导致的 Layout 异常渲染问题
if (self.scrollView.mj_insetT != insetT) {
self.scrollView.mj_insetT = insetT; self.scrollView.mj_insetT = insetT;
}
}
self.insetTDelta = _scrollViewOriginalInset.top - insetT;
- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change
{
[super scrollViewContentOffsetDidChange:change];
// 在刷新的refreshing状态
if (self.state == MJRefreshStateRefreshing) {
[self resetInset];
return; return;
} }
...@@ -114,6 +125,9 @@ ...@@ -114,6 +125,9 @@
[UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{ [UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{
self.scrollView.mj_insetT += self.insetTDelta; self.scrollView.mj_insetT += self.insetTDelta;
if (self.endRefreshingAnimateCompletionBlock) {
self.endRefreshingAnimateCompletionBlock();
}
// 自动调整透明度 // 自动调整透明度
if (self.isAutomaticallyChangeAlpha) self.alpha = 0.0; if (self.isAutomaticallyChangeAlpha) self.alpha = 0.0;
} completion:^(BOOL finished) { } completion:^(BOOL finished) {
...@@ -124,8 +138,9 @@ ...@@ -124,8 +138,9 @@
} }
}]; }];
} else if (state == MJRefreshStateRefreshing) { } else if (state == MJRefreshStateRefreshing) {
dispatch_async(dispatch_get_main_queue(), ^{ MJRefreshDispatchAsyncOnMainQueue({
[UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{
if (self.scrollView.panGestureRecognizer.state != UIGestureRecognizerStateCancelled) {
CGFloat top = self.scrollViewOriginalInset.top + self.mj_h; CGFloat top = self.scrollViewOriginalInset.top + self.mj_h;
// 增加滚动区域top // 增加滚动区域top
self.scrollView.mj_insetT = top; self.scrollView.mj_insetT = top;
...@@ -133,10 +148,11 @@ ...@@ -133,10 +148,11 @@
CGPoint offset = self.scrollView.contentOffset; CGPoint offset = self.scrollView.contentOffset;
offset.y = -top; offset.y = -top;
[self.scrollView setContentOffset:offset animated:NO]; [self.scrollView setContentOffset:offset animated:NO];
}
} completion:^(BOOL finished) { } completion:^(BOOL finished) {
[self executeRefreshingCallback]; [self executeRefreshingCallback];
}]; }];
}); })
} }
} }
...@@ -145,4 +161,11 @@ ...@@ -145,4 +161,11 @@
{ {
return [[NSUserDefaults standardUserDefaults] objectForKey:self.lastUpdatedTimeKey]; return [[NSUserDefaults standardUserDefaults] objectForKey:self.lastUpdatedTimeKey];
} }
- (void)setIgnoredScrollViewContentInsetTop:(CGFloat)ignoredScrollViewContentInsetTop {
_ignoredScrollViewContentInsetTop = ignoredScrollViewContentInsetTop;
self.mj_y = - self.mj_h - _ignoredScrollViewContentInsetTop;
}
@end @end
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#import "MJRefreshAutoStateFooter.h" #import "MJRefreshAutoStateFooter.h"
NS_ASSUME_NONNULL_BEGIN
@interface MJRefreshAutoGifFooter : MJRefreshAutoStateFooter @interface MJRefreshAutoGifFooter : MJRefreshAutoStateFooter
@property (weak, nonatomic, readonly) UIImageView *gifView; @property (weak, nonatomic, readonly) UIImageView *gifView;
...@@ -15,3 +17,5 @@ ...@@ -15,3 +17,5 @@
- (void)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state; - (void)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state;
- (void)setImages:(NSArray *)images forState:(MJRefreshState)state; - (void)setImages:(NSArray *)images forState:(MJRefreshState)state;
@end @end
NS_ASSUME_NONNULL_END
...@@ -85,7 +85,7 @@ ...@@ -85,7 +85,7 @@
self.gifView.contentMode = UIViewContentModeCenter; self.gifView.contentMode = UIViewContentModeCenter;
} else { } else {
self.gifView.contentMode = UIViewContentModeRight; self.gifView.contentMode = UIViewContentModeRight;
self.gifView.mj_w = self.mj_w * 0.5 - self.labelLeftInset - self.stateLabel.mj_textWith * 0.5; self.gifView.mj_w = self.mj_w * 0.5 - self.labelLeftInset - self.stateLabel.mj_textWidth * 0.5;
} }
} }
......
...@@ -8,7 +8,14 @@ ...@@ -8,7 +8,14 @@
#import "MJRefreshAutoStateFooter.h" #import "MJRefreshAutoStateFooter.h"
NS_ASSUME_NONNULL_BEGIN
@interface MJRefreshAutoNormalFooter : MJRefreshAutoStateFooter @interface MJRefreshAutoNormalFooter : MJRefreshAutoStateFooter
@property (weak, nonatomic, readonly) UIActivityIndicatorView *loadingView;
/** 菊花的样式 */ /** 菊花的样式 */
@property (assign, nonatomic) UIActivityIndicatorViewStyle activityIndicatorViewStyle; @property (assign, nonatomic) UIActivityIndicatorViewStyle activityIndicatorViewStyle __attribute__((deprecated("first deprecated in 3.2.2 - Use `loadingView` property")));
@end @end
NS_ASSUME_NONNULL_END
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
- (UIActivityIndicatorView *)loadingView - (UIActivityIndicatorView *)loadingView
{ {
if (!_loadingView) { if (!_loadingView) {
UIActivityIndicatorView *loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:self.activityIndicatorViewStyle]; UIActivityIndicatorView *loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:_activityIndicatorViewStyle];
loadingView.hidesWhenStopped = YES; loadingView.hidesWhenStopped = YES;
[self addSubview:_loadingView = loadingView]; [self addSubview:_loadingView = loadingView];
} }
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
{ {
_activityIndicatorViewStyle = activityIndicatorViewStyle; _activityIndicatorViewStyle = activityIndicatorViewStyle;
[self.loadingView removeFromSuperview];
self.loadingView = nil; self.loadingView = nil;
[self setNeedsLayout]; [self setNeedsLayout];
} }
...@@ -36,7 +37,14 @@ ...@@ -36,7 +37,14 @@
{ {
[super prepare]; [super prepare];
self.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray; #if __IPHONE_OS_VERSION_MAX_ALLOWED > 130000
if (@available(iOS 13.0, *)) {
_activityIndicatorViewStyle = UIActivityIndicatorViewStyleMedium;
return;
}
#endif
_activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;
} }
- (void)placeSubviews - (void)placeSubviews
...@@ -48,7 +56,7 @@ ...@@ -48,7 +56,7 @@
// 圈圈 // 圈圈
CGFloat loadingCenterX = self.mj_w * 0.5; CGFloat loadingCenterX = self.mj_w * 0.5;
if (!self.isRefreshingTitleHidden) { if (!self.isRefreshingTitleHidden) {
loadingCenterX -= self.stateLabel.mj_textWith * 0.5 + self.labelLeftInset; loadingCenterX -= self.stateLabel.mj_textWidth * 0.5 + self.labelLeftInset;
} }
CGFloat loadingCenterY = self.mj_h * 0.5; CGFloat loadingCenterY = self.mj_h * 0.5;
self.loadingView.center = CGPointMake(loadingCenterX, loadingCenterY); self.loadingView.center = CGPointMake(loadingCenterX, loadingCenterY);
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#import "MJRefreshAutoFooter.h" #import "MJRefreshAutoFooter.h"
NS_ASSUME_NONNULL_BEGIN
@interface MJRefreshAutoStateFooter : MJRefreshAutoFooter @interface MJRefreshAutoStateFooter : MJRefreshAutoFooter
/** 文字距离圈圈、箭头的距离 */ /** 文字距离圈圈、箭头的距离 */
@property (assign, nonatomic) CGFloat labelLeftInset; @property (assign, nonatomic) CGFloat labelLeftInset;
...@@ -20,3 +22,5 @@ ...@@ -20,3 +22,5 @@
/** 隐藏刷新状态的文字 */ /** 隐藏刷新状态的文字 */
@property (assign, nonatomic, getter=isRefreshingTitleHidden) BOOL refreshingTitleHidden; @property (assign, nonatomic, getter=isRefreshingTitleHidden) BOOL refreshingTitleHidden;
@end @end
NS_ASSUME_NONNULL_END
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
} }
/** 所有状态对应的文字 */ /** 所有状态对应的文字 */
@property (strong, nonatomic) NSMutableDictionary *stateTitles; @property (strong, nonatomic) NSMutableDictionary *stateTitles;
/** 用于判断点击 Label 触发特殊的刷新逻辑 */
@property (assign, nonatomic) BOOL labelIsTrigger;
@end @end
@implementation MJRefreshAutoStateFooter @implementation MJRefreshAutoStateFooter
...@@ -43,11 +45,17 @@ ...@@ -43,11 +45,17 @@
self.stateLabel.text = self.stateTitles[@(self.state)]; self.stateLabel.text = self.stateTitles[@(self.state)];
} }
- (BOOL)ignoreRefreshAction {
return !self.labelIsTrigger && [super ignoreRefreshAction];
}
#pragma mark - 私有方法 #pragma mark - 私有方法
- (void)stateLabelClick - (void)stateLabelClick
{ {
if (self.state == MJRefreshStateIdle) { if (self.state == MJRefreshStateIdle) {
self.labelIsTrigger = YES;
[self beginRefreshing]; [self beginRefreshing];
self.labelIsTrigger = NO;
} }
} }
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#import "MJRefreshBackStateFooter.h" #import "MJRefreshBackStateFooter.h"
NS_ASSUME_NONNULL_BEGIN
@interface MJRefreshBackGifFooter : MJRefreshBackStateFooter @interface MJRefreshBackGifFooter : MJRefreshBackStateFooter
@property (weak, nonatomic, readonly) UIImageView *gifView; @property (weak, nonatomic, readonly) UIImageView *gifView;
...@@ -15,3 +17,5 @@ ...@@ -15,3 +17,5 @@
- (void)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state; - (void)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state;
- (void)setImages:(NSArray *)images forState:(MJRefreshState)state; - (void)setImages:(NSArray *)images forState:(MJRefreshState)state;
@end @end
NS_ASSUME_NONNULL_END
...@@ -96,7 +96,7 @@ ...@@ -96,7 +96,7 @@
self.gifView.contentMode = UIViewContentModeCenter; self.gifView.contentMode = UIViewContentModeCenter;
} else { } else {
self.gifView.contentMode = UIViewContentModeRight; self.gifView.contentMode = UIViewContentModeRight;
self.gifView.mj_w = self.mj_w * 0.5 - self.labelLeftInset - self.stateLabel.mj_textWith * 0.5; self.gifView.mj_w = self.mj_w * 0.5 - self.labelLeftInset - self.stateLabel.mj_textWidth * 0.5;
} }
} }
......
...@@ -8,8 +8,14 @@ ...@@ -8,8 +8,14 @@
#import "MJRefreshBackStateFooter.h" #import "MJRefreshBackStateFooter.h"
NS_ASSUME_NONNULL_BEGIN
@interface MJRefreshBackNormalFooter : MJRefreshBackStateFooter @interface MJRefreshBackNormalFooter : MJRefreshBackStateFooter
@property (weak, nonatomic, readonly) UIImageView *arrowView; @property (weak, nonatomic, readonly) UIImageView *arrowView;
@property (weak, nonatomic, readonly) UIActivityIndicatorView *loadingView;
/** 菊花的样式 */ /** 菊花的样式 */
@property (assign, nonatomic) UIActivityIndicatorViewStyle activityIndicatorViewStyle; @property (assign, nonatomic) UIActivityIndicatorViewStyle activityIndicatorViewStyle __attribute__((deprecated("first deprecated in 3.2.2 - Use `loadingView` property")));
@end @end
NS_ASSUME_NONNULL_END
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
- (UIActivityIndicatorView *)loadingView - (UIActivityIndicatorView *)loadingView
{ {
if (!_loadingView) { if (!_loadingView) {
UIActivityIndicatorView *loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:self.activityIndicatorViewStyle]; UIActivityIndicatorView *loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:_activityIndicatorViewStyle];
loadingView.hidesWhenStopped = YES; loadingView.hidesWhenStopped = YES;
[self addSubview:_loadingView = loadingView]; [self addSubview:_loadingView = loadingView];
} }
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
{ {
_activityIndicatorViewStyle = activityIndicatorViewStyle; _activityIndicatorViewStyle = activityIndicatorViewStyle;
[self.loadingView removeFromSuperview];
self.loadingView = nil; self.loadingView = nil;
[self setNeedsLayout]; [self setNeedsLayout];
} }
...@@ -50,7 +51,14 @@ ...@@ -50,7 +51,14 @@
{ {
[super prepare]; [super prepare];
self.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray; #if __IPHONE_OS_VERSION_MAX_ALLOWED > 130000
if (@available(iOS 13.0, *)) {
_activityIndicatorViewStyle = UIActivityIndicatorViewStyleMedium;
return;
}
#endif
_activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;
} }
- (void)placeSubviews - (void)placeSubviews
...@@ -60,7 +68,7 @@ ...@@ -60,7 +68,7 @@
// 箭头的中心点 // 箭头的中心点
CGFloat arrowCenterX = self.mj_w * 0.5; CGFloat arrowCenterX = self.mj_w * 0.5;
if (!self.stateLabel.hidden) { if (!self.stateLabel.hidden) {
arrowCenterX -= self.labelLeftInset + self.stateLabel.mj_textWith * 0.5; arrowCenterX -= self.labelLeftInset + self.stateLabel.mj_textWidth * 0.5;
} }
CGFloat arrowCenterY = self.mj_h * 0.5; CGFloat arrowCenterY = self.mj_h * 0.5;
CGPoint arrowCenter = CGPointMake(arrowCenterX, arrowCenterY); CGPoint arrowCenter = CGPointMake(arrowCenterX, arrowCenterY);
...@@ -90,6 +98,9 @@ ...@@ -90,6 +98,9 @@
[UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{ [UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{
self.loadingView.alpha = 0.0; self.loadingView.alpha = 0.0;
} completion:^(BOOL finished) { } completion:^(BOOL finished) {
// 防止动画结束后,状态已经不是MJRefreshStateIdle
if (self.state != MJRefreshStateIdle) return;
self.loadingView.alpha = 1.0; self.loadingView.alpha = 1.0;
[self.loadingView stopAnimating]; [self.loadingView stopAnimating];
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#import "MJRefreshBackFooter.h" #import "MJRefreshBackFooter.h"
NS_ASSUME_NONNULL_BEGIN
@interface MJRefreshBackStateFooter : MJRefreshBackFooter @interface MJRefreshBackStateFooter : MJRefreshBackFooter
/** 文字距离圈圈、箭头的距离 */ /** 文字距离圈圈、箭头的距离 */
@property (assign, nonatomic) CGFloat labelLeftInset; @property (assign, nonatomic) CGFloat labelLeftInset;
...@@ -19,3 +21,5 @@ ...@@ -19,3 +21,5 @@
/** 获取state状态下的title */ /** 获取state状态下的title */
- (NSString *)titleForState:(MJRefreshState)state; - (NSString *)titleForState:(MJRefreshState)state;
@end @end
NS_ASSUME_NONNULL_END
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#import "MJRefreshStateHeader.h" #import "MJRefreshStateHeader.h"
NS_ASSUME_NONNULL_BEGIN
@interface MJRefreshGifHeader : MJRefreshStateHeader @interface MJRefreshGifHeader : MJRefreshStateHeader
@property (weak, nonatomic, readonly) UIImageView *gifView; @property (weak, nonatomic, readonly) UIImageView *gifView;
...@@ -15,3 +17,5 @@ ...@@ -15,3 +17,5 @@
- (void)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state; - (void)setImages:(NSArray *)images duration:(NSTimeInterval)duration forState:(MJRefreshState)state;
- (void)setImages:(NSArray *)images forState:(MJRefreshState)state; - (void)setImages:(NSArray *)images forState:(MJRefreshState)state;
@end @end
NS_ASSUME_NONNULL_END
...@@ -99,10 +99,10 @@ ...@@ -99,10 +99,10 @@
} else { } else {
self.gifView.contentMode = UIViewContentModeRight; self.gifView.contentMode = UIViewContentModeRight;
CGFloat stateWidth = self.stateLabel.mj_textWith; CGFloat stateWidth = self.stateLabel.mj_textWidth;
CGFloat timeWidth = 0.0; CGFloat timeWidth = 0.0;
if (!self.lastUpdatedTimeLabel.hidden) { if (!self.lastUpdatedTimeLabel.hidden) {
timeWidth = self.lastUpdatedTimeLabel.mj_textWith; timeWidth = self.lastUpdatedTimeLabel.mj_textWidth;
} }
CGFloat textWidth = MAX(stateWidth, timeWidth); CGFloat textWidth = MAX(stateWidth, timeWidth);
self.gifView.mj_w = self.mj_w * 0.5 - textWidth * 0.5 - self.labelLeftInset; self.gifView.mj_w = self.mj_w * 0.5 - textWidth * 0.5 - self.labelLeftInset;
......
...@@ -8,8 +8,15 @@ ...@@ -8,8 +8,15 @@
#import "MJRefreshStateHeader.h" #import "MJRefreshStateHeader.h"
NS_ASSUME_NONNULL_BEGIN
@interface MJRefreshNormalHeader : MJRefreshStateHeader @interface MJRefreshNormalHeader : MJRefreshStateHeader
@property (weak, nonatomic, readonly) UIImageView *arrowView; @property (weak, nonatomic, readonly) UIImageView *arrowView;
@property (weak, nonatomic, readonly) UIActivityIndicatorView *loadingView;
/** 菊花的样式 */ /** 菊花的样式 */
@property (assign, nonatomic) UIActivityIndicatorViewStyle activityIndicatorViewStyle; @property (assign, nonatomic) UIActivityIndicatorViewStyle activityIndicatorViewStyle __attribute__((deprecated("first deprecated in 3.2.2 - Use `loadingView` property")));
@end @end
NS_ASSUME_NONNULL_END
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
- (UIActivityIndicatorView *)loadingView - (UIActivityIndicatorView *)loadingView
{ {
if (!_loadingView) { if (!_loadingView) {
UIActivityIndicatorView *loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:self.activityIndicatorViewStyle]; UIActivityIndicatorView *loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:_activityIndicatorViewStyle];
loadingView.hidesWhenStopped = YES; loadingView.hidesWhenStopped = YES;
[self addSubview:_loadingView = loadingView]; [self addSubview:_loadingView = loadingView];
} }
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
{ {
_activityIndicatorViewStyle = activityIndicatorViewStyle; _activityIndicatorViewStyle = activityIndicatorViewStyle;
[self.loadingView removeFromSuperview];
self.loadingView = nil; self.loadingView = nil;
[self setNeedsLayout]; [self setNeedsLayout];
} }
...@@ -51,7 +52,14 @@ ...@@ -51,7 +52,14 @@
{ {
[super prepare]; [super prepare];
self.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray; #if __IPHONE_OS_VERSION_MAX_ALLOWED > 130000
if (@available(iOS 13.0, *)) {
_activityIndicatorViewStyle = UIActivityIndicatorViewStyleMedium;
return;
}
#endif
_activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;
} }
- (void)placeSubviews - (void)placeSubviews
...@@ -61,10 +69,10 @@ ...@@ -61,10 +69,10 @@
// 箭头的中心点 // 箭头的中心点
CGFloat arrowCenterX = self.mj_w * 0.5; CGFloat arrowCenterX = self.mj_w * 0.5;
if (!self.stateLabel.hidden) { if (!self.stateLabel.hidden) {
CGFloat stateWidth = self.stateLabel.mj_textWith; CGFloat stateWidth = self.stateLabel.mj_textWidth;
CGFloat timeWidth = 0.0; CGFloat timeWidth = 0.0;
if (!self.lastUpdatedTimeLabel.hidden) { if (!self.lastUpdatedTimeLabel.hidden) {
timeWidth = self.lastUpdatedTimeLabel.mj_textWith; timeWidth = self.lastUpdatedTimeLabel.mj_textWidth;
} }
CGFloat textWidth = MAX(stateWidth, timeWidth); CGFloat textWidth = MAX(stateWidth, timeWidth);
arrowCenterX -= textWidth / 2 + self.labelLeftInset; arrowCenterX -= textWidth / 2 + self.labelLeftInset;
......
...@@ -8,10 +8,12 @@ ...@@ -8,10 +8,12 @@
#import "MJRefreshHeader.h" #import "MJRefreshHeader.h"
NS_ASSUME_NONNULL_BEGIN
@interface MJRefreshStateHeader : MJRefreshHeader @interface MJRefreshStateHeader : MJRefreshHeader
#pragma mark - 刷新时间相关 #pragma mark - 刷新时间相关
/** 利用这个block来决定显示的更新时间文字 */ /** 利用这个block来决定显示的更新时间文字 */
@property (copy, nonatomic) NSString *(^lastUpdatedTimeText)(NSDate *lastUpdatedTime); @property (copy, nonatomic, nullable) NSString *(^lastUpdatedTimeText)(NSDate *lastUpdatedTime);
/** 显示上一次刷新时间的label */ /** 显示上一次刷新时间的label */
@property (weak, nonatomic, readonly) UILabel *lastUpdatedTimeLabel; @property (weak, nonatomic, readonly) UILabel *lastUpdatedTimeLabel;
...@@ -23,3 +25,5 @@ ...@@ -23,3 +25,5 @@
/** 设置state状态下的文字 */ /** 设置state状态下的文字 */
- (void)setTitle:(NSString *)title forState:(MJRefreshState)state; - (void)setTitle:(NSString *)title forState:(MJRefreshState)state;
@end @end
NS_ASSUME_NONNULL_END
...@@ -53,14 +53,6 @@ ...@@ -53,14 +53,6 @@
self.stateLabel.text = self.stateTitles[@(self.state)]; self.stateLabel.text = self.stateTitles[@(self.state)];
} }
#pragma mark - 日历获取在9.x之后的系统使用currentCalendar会出异常。在8.0之后使用系统新API。
- (NSCalendar *)currentCalendar {
if ([NSCalendar respondsToSelector:@selector(calendarWithIdentifier:)]) {
return [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
}
return [NSCalendar currentCalendar];
}
#pragma mark key的处理 #pragma mark key的处理
- (void)setLastUpdatedTimeKey:(NSString *)lastUpdatedTimeKey - (void)setLastUpdatedTimeKey:(NSString *)lastUpdatedTimeKey
{ {
...@@ -79,8 +71,8 @@ ...@@ -79,8 +71,8 @@
if (lastUpdatedTime) { if (lastUpdatedTime) {
// 1.获得年月日 // 1.获得年月日
NSCalendar *calendar = [self currentCalendar]; NSCalendar *calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
NSUInteger unitFlags = NSCalendarUnitYear| NSCalendarUnitMonth | NSCalendarUnitDay |NSCalendarUnitHour |NSCalendarUnitMinute; NSUInteger unitFlags = NSCalendarUnitYear| NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute;
NSDateComponents *cmp1 = [calendar components:unitFlags fromDate:lastUpdatedTime]; NSDateComponents *cmp1 = [calendar components:unitFlags fromDate:lastUpdatedTime];
NSDateComponents *cmp2 = [calendar components:unitFlags fromDate:[NSDate date]]; NSDateComponents *cmp2 = [calendar components:unitFlags fromDate:[NSDate date]];
......
B"MJRefreshHeaderIdleText" = "Pull down to refresh"; B"MJRefreshHeaderIdleText" = "Pull down to refresh";
......
File mode changed from 100644 to 100755
//
// MJRefreshConfig.h
//
// Created by Frank on 2018/11/27.
// Copyright © 2018 小码哥. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface MJRefreshConfig : NSObject
/** 默认使用的语言版本, 默认为 nil. 将随系统的语言自动改变 */
@property (copy, nonatomic, nullable) NSString *languageCode;
/** @return Singleton Config instance */
+ (instancetype)defaultConfig;
- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END
//
// MJRefreshConfig.m
//
// Created by Frank on 2018/11/27.
// Copyright © 2018 小码哥. All rights reserved.
//
#import "MJRefreshConfig.h"
@implementation MJRefreshConfig
static MJRefreshConfig *mj_RefreshConfig = nil;
+ (instancetype)defaultConfig {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
mj_RefreshConfig = [[self alloc] init];
});
return mj_RefreshConfig;
}
@end
...@@ -65,3 +65,11 @@ UIKIT_EXTERN NSString *const MJRefreshHeaderNoneLastDateText; ...@@ -65,3 +65,11 @@ UIKIT_EXTERN NSString *const MJRefreshHeaderNoneLastDateText;
MJRefreshState oldState = self.state; \ MJRefreshState oldState = self.state; \
if (state == oldState) return; \ if (state == oldState) return; \
[super setState:state]; [super setState:state];
// 异步主线程执行,不强持有Self
#define MJRefreshDispatchAsyncOnMainQueue(x) \
__weak typeof(self) weakSelf = self; \
dispatch_async(dispatch_get_main_queue(), ^{ \
typeof(weakSelf) self = weakSelf; \
{x} \
});
File mode changed from 100644 to 100755
...@@ -8,9 +8,13 @@ ...@@ -8,9 +8,13 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSBundle (MJRefresh) @interface NSBundle (MJRefresh)
+ (instancetype)mj_refreshBundle; + (instancetype)mj_refreshBundle;
+ (UIImage *)mj_arrowImage; + (UIImage *)mj_arrowImage;
+ (NSString *)mj_localizedStringForKey:(NSString *)key value:(NSString *)value; + (NSString *)mj_localizedStringForKey:(NSString *)key value:(nullable NSString *)value;
+ (NSString *)mj_localizedStringForKey:(NSString *)key; + (NSString *)mj_localizedStringForKey:(NSString *)key;
@end @end
NS_ASSUME_NONNULL_END
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#import "NSBundle+MJRefresh.h" #import "NSBundle+MJRefresh.h"
#import "MJRefreshComponent.h" #import "MJRefreshComponent.h"
#import "MJRefreshConfig.h"
@implementation NSBundle (MJRefresh) @implementation NSBundle (MJRefresh)
+ (instancetype)mj_refreshBundle + (instancetype)mj_refreshBundle
...@@ -24,7 +25,7 @@ ...@@ -24,7 +25,7 @@
{ {
static UIImage *arrowImage = nil; static UIImage *arrowImage = nil;
if (arrowImage == nil) { if (arrowImage == nil) {
arrowImage = [[UIImage imageWithContentsOfFile:[[self mj_refreshBundle] pathForResource:@"gm_arrow@2x" ofType:@"png"]] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; arrowImage = [[UIImage imageWithContentsOfFile:[[self mj_refreshBundle] pathForResource:@"arrow@2x" ofType:@"png"]] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
} }
return arrowImage; return arrowImage;
} }
...@@ -38,8 +39,13 @@ ...@@ -38,8 +39,13 @@
{ {
static NSBundle *bundle = nil; static NSBundle *bundle = nil;
if (bundle == nil) { if (bundle == nil) {
NSString *language = MJRefreshConfig.defaultConfig.languageCode;
// 如果配置中没有配置语言
if (!language) {
// (iOS获取的语言字符串比较不稳定)目前框架只处理en、zh-Hans、zh-Hant三种情况,其他按照系统默认处理 // (iOS获取的语言字符串比较不稳定)目前框架只处理en、zh-Hans、zh-Hant三种情况,其他按照系统默认处理
NSString *language = [NSLocale preferredLanguages].firstObject; language = [NSLocale preferredLanguages].firstObject;
}
if ([language hasPrefix:@"en"]) { if ([language hasPrefix:@"en"]) {
language = @"en"; language = @"en";
} else if ([language hasPrefix:@"zh"]) { } else if ([language hasPrefix:@"zh"]) {
...@@ -48,6 +54,12 @@ ...@@ -48,6 +54,12 @@
} else { // zh-Hant\zh-HK\zh-TW } else { // zh-Hant\zh-HK\zh-TW
language = @"zh-Hant"; // 繁體中文 language = @"zh-Hant"; // 繁體中文
} }
} else if ([language hasPrefix:@"ko"]) {
language = @"ko";
} else if ([language hasPrefix:@"ru"]) {
language = @"ru";
} else if ([language hasPrefix:@"uk"]) {
language = @"uk";
} else { } else {
language = @"en"; language = @"en";
} }
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UIScrollView (MJExtension) @interface UIScrollView (MJExtension)
@property (readonly, nonatomic) UIEdgeInsets mj_inset; @property (readonly, nonatomic) UIEdgeInsets mj_inset;
...@@ -23,3 +25,5 @@ ...@@ -23,3 +25,5 @@
@property (assign, nonatomic) CGFloat mj_contentW; @property (assign, nonatomic) CGFloat mj_contentW;
@property (assign, nonatomic) CGFloat mj_contentH; @property (assign, nonatomic) CGFloat mj_contentH;
@end @end
NS_ASSUME_NONNULL_END
...@@ -10,17 +10,25 @@ ...@@ -10,17 +10,25 @@
#import "UIScrollView+MJExtension.h" #import "UIScrollView+MJExtension.h"
#import <objc/runtime.h> #import <objc/runtime.h>
#define SYSTEM_VERSION_GREATER_NOT_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#pragma clang diagnostic push #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability-new" #pragma clang diagnostic ignored "-Wunguarded-availability-new"
@implementation UIScrollView (MJExtension) @implementation UIScrollView (MJExtension)
static BOOL respondsToAdjustedContentInset_;
+ (void)initialize
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
respondsToAdjustedContentInset_ = [self instancesRespondToSelector:@selector(adjustedContentInset)];
});
}
- (UIEdgeInsets)mj_inset - (UIEdgeInsets)mj_inset
{ {
#ifdef __IPHONE_11_0 #ifdef __IPHONE_11_0
if (SYSTEM_VERSION_GREATER_NOT_LESS_THAN(@"11.0") && [self respondsToSelector:@selector(adjustedContentInset)]) { if (respondsToAdjustedContentInset_) {
return self.adjustedContentInset; return self.adjustedContentInset;
} }
#endif #endif
...@@ -32,7 +40,7 @@ ...@@ -32,7 +40,7 @@
UIEdgeInsets inset = self.contentInset; UIEdgeInsets inset = self.contentInset;
inset.top = mj_insetT; inset.top = mj_insetT;
#ifdef __IPHONE_11_0 #ifdef __IPHONE_11_0
if (SYSTEM_VERSION_GREATER_NOT_LESS_THAN(@"11.0") && [self respondsToSelector:@selector(adjustedContentInset)]) { if (respondsToAdjustedContentInset_) {
inset.top -= (self.adjustedContentInset.top - self.contentInset.top); inset.top -= (self.adjustedContentInset.top - self.contentInset.top);
} }
#endif #endif
...@@ -49,7 +57,7 @@ ...@@ -49,7 +57,7 @@
UIEdgeInsets inset = self.contentInset; UIEdgeInsets inset = self.contentInset;
inset.bottom = mj_insetB; inset.bottom = mj_insetB;
#ifdef __IPHONE_11_0 #ifdef __IPHONE_11_0
if (SYSTEM_VERSION_GREATER_NOT_LESS_THAN(@"11.0") && [self respondsToSelector:@selector(adjustedContentInset)]) { if (respondsToAdjustedContentInset_) {
inset.bottom -= (self.adjustedContentInset.bottom - self.contentInset.bottom); inset.bottom -= (self.adjustedContentInset.bottom - self.contentInset.bottom);
} }
#endif #endif
...@@ -66,7 +74,7 @@ ...@@ -66,7 +74,7 @@
UIEdgeInsets inset = self.contentInset; UIEdgeInsets inset = self.contentInset;
inset.left = mj_insetL; inset.left = mj_insetL;
#ifdef __IPHONE_11_0 #ifdef __IPHONE_11_0
if (SYSTEM_VERSION_GREATER_NOT_LESS_THAN(@"11.0") && [self respondsToSelector:@selector(adjustedContentInset)]) { if (respondsToAdjustedContentInset_) {
inset.left -= (self.adjustedContentInset.left - self.contentInset.left); inset.left -= (self.adjustedContentInset.left - self.contentInset.left);
} }
#endif #endif
...@@ -83,7 +91,7 @@ ...@@ -83,7 +91,7 @@
UIEdgeInsets inset = self.contentInset; UIEdgeInsets inset = self.contentInset;
inset.right = mj_insetR; inset.right = mj_insetR;
#ifdef __IPHONE_11_0 #ifdef __IPHONE_11_0
if (SYSTEM_VERSION_GREATER_NOT_LESS_THAN(@"11.0") && [self respondsToSelector:@selector(adjustedContentInset)]) { if (respondsToAdjustedContentInset_) {
inset.right -= (self.adjustedContentInset.right - self.contentInset.right); inset.right -= (self.adjustedContentInset.right - self.contentInset.right);
} }
#endif #endif
......
...@@ -12,20 +12,19 @@ ...@@ -12,20 +12,19 @@
@class MJRefreshHeader, MJRefreshFooter; @class MJRefreshHeader, MJRefreshFooter;
@interface NSObject (MJRefresh) NS_ASSUME_NONNULL_BEGIN
+ (void)exchangeInstanceMethod1:(SEL)method1 method2:(SEL)method2;
+ (void)exchangeClassMethod1:(SEL)method1 method2:(SEL)method2;
@end
@interface UIScrollView (MJRefresh) @interface UIScrollView (MJRefresh)
/** 下拉刷新控件 */ /** 下拉刷新控件 */
@property (strong, nonatomic) MJRefreshHeader *mj_header; @property (strong, nonatomic, nullable) MJRefreshHeader *mj_header;
@property (strong, nonatomic) MJRefreshHeader *header MJRefreshDeprecated("使用mj_header"); @property (strong, nonatomic, nullable) MJRefreshHeader *header MJRefreshDeprecated("使用mj_header");
/** 上拉刷新控件 */ /** 上拉刷新控件 */
@property (strong, nonatomic) MJRefreshFooter *mj_footer; @property (strong, nonatomic, nullable) MJRefreshFooter *mj_footer;
@property (strong, nonatomic) MJRefreshFooter *footer MJRefreshDeprecated("使用mj_footer"); @property (strong, nonatomic, nullable) MJRefreshFooter *footer MJRefreshDeprecated("使用mj_footer");
#pragma mark - other #pragma mark - other
- (NSInteger)mj_totalDataCount; - (NSInteger)mj_totalDataCount;
@property (copy, nonatomic) void (^mj_reloadDataBlock)(NSInteger totalDataCount);
@end @end
NS_ASSUME_NONNULL_END
...@@ -12,20 +12,6 @@ ...@@ -12,20 +12,6 @@
#import "MJRefreshFooter.h" #import "MJRefreshFooter.h"
#import <objc/runtime.h> #import <objc/runtime.h>
@implementation NSObject (MJRefresh)
+ (void)exchangeInstanceMethod1:(SEL)method1 method2:(SEL)method2
{
method_exchangeImplementations(class_getInstanceMethod(self, method1), class_getInstanceMethod(self, method2));
}
+ (void)exchangeClassMethod1:(SEL)method1 method2:(SEL)method2
{
method_exchangeImplementations(class_getClassMethod(self, method1), class_getClassMethod(self, method2));
}
@end
@implementation UIScrollView (MJRefresh) @implementation UIScrollView (MJRefresh)
#pragma mark - header #pragma mark - header
...@@ -38,10 +24,8 @@ static const char MJRefreshHeaderKey = '\0'; ...@@ -38,10 +24,8 @@ static const char MJRefreshHeaderKey = '\0';
[self insertSubview:mj_header atIndex:0]; [self insertSubview:mj_header atIndex:0];
// 存储新的 // 存储新的
[self willChangeValueForKey:@"mj_header"]; // KVO
objc_setAssociatedObject(self, &MJRefreshHeaderKey, objc_setAssociatedObject(self, &MJRefreshHeaderKey,
mj_header, OBJC_ASSOCIATION_ASSIGN); mj_header, OBJC_ASSOCIATION_RETAIN);
[self didChangeValueForKey:@"mj_header"]; // KVO
} }
} }
...@@ -60,10 +44,8 @@ static const char MJRefreshFooterKey = '\0'; ...@@ -60,10 +44,8 @@ static const char MJRefreshFooterKey = '\0';
[self insertSubview:mj_footer atIndex:0]; [self insertSubview:mj_footer atIndex:0];
// 存储新的 // 存储新的
[self willChangeValueForKey:@"mj_footer"]; // KVO
objc_setAssociatedObject(self, &MJRefreshFooterKey, objc_setAssociatedObject(self, &MJRefreshFooterKey,
mj_footer, OBJC_ASSOCIATION_ASSIGN); mj_footer, OBJC_ASSOCIATION_RETAIN);
[self didChangeValueForKey:@"mj_footer"]; // KVO
} }
} }
...@@ -100,54 +82,17 @@ static const char MJRefreshFooterKey = '\0'; ...@@ -100,54 +82,17 @@ static const char MJRefreshFooterKey = '\0';
if ([self isKindOfClass:[UITableView class]]) { if ([self isKindOfClass:[UITableView class]]) {
UITableView *tableView = (UITableView *)self; UITableView *tableView = (UITableView *)self;
for (NSInteger section = 0; section<tableView.numberOfSections; section++) { for (NSInteger section = 0; section < tableView.numberOfSections; section++) {
totalCount += [tableView numberOfRowsInSection:section]; totalCount += [tableView numberOfRowsInSection:section];
} }
} else if ([self isKindOfClass:[UICollectionView class]]) { } else if ([self isKindOfClass:[UICollectionView class]]) {
UICollectionView *collectionView = (UICollectionView *)self; UICollectionView *collectionView = (UICollectionView *)self;
for (NSInteger section = 0; section<collectionView.numberOfSections; section++) { for (NSInteger section = 0; section < collectionView.numberOfSections; section++) {
totalCount += [collectionView numberOfItemsInSection:section]; totalCount += [collectionView numberOfItemsInSection:section];
} }
} }
return totalCount; return totalCount;
} }
static const char MJRefreshReloadDataBlockKey = '\0';
- (void)setMj_reloadDataBlock:(void (^)(NSInteger))mj_reloadDataBlock
{
[self willChangeValueForKey:@"mj_reloadDataBlock"]; // KVO
objc_setAssociatedObject(self, &MJRefreshReloadDataBlockKey, mj_reloadDataBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
[self didChangeValueForKey:@"mj_reloadDataBlock"]; // KVO
}
- (void (^)(NSInteger))mj_reloadDataBlock
{
return objc_getAssociatedObject(self, &MJRefreshReloadDataBlockKey);
}
- (void)executeReloadDataBlock
{
!self.mj_reloadDataBlock ? : self.mj_reloadDataBlock(self.mj_totalDataCount);
}
@end
@implementation UITableView (MJRefresh)
- (void)mj_reloadData
{
[self mj_reloadData];
[self executeReloadDataBlock];
}
@end
@implementation UICollectionView (MJRefresh)
- (void)mj_reloadData
{
[self mj_reloadData];
[self executeReloadDataBlock];
}
@end @end
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface UIView (MJExtension) @interface UIView (MJExtension)
@property (assign, nonatomic) CGFloat mj_x; @property (assign, nonatomic) CGFloat mj_x;
@property (assign, nonatomic) CGFloat mj_y; @property (assign, nonatomic) CGFloat mj_y;
...@@ -17,3 +19,5 @@ ...@@ -17,3 +19,5 @@
@property (assign, nonatomic) CGSize mj_size; @property (assign, nonatomic) CGSize mj_size;
@property (assign, nonatomic) CGPoint mj_origin; @property (assign, nonatomic) CGPoint mj_origin;
@end @end
NS_ASSUME_NONNULL_END
File mode changed from 100644 to 100755
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment