Przeglądaj źródła

Change code style

M了个J 11 lat temu
rodzic
commit
7dede04f59

+ 4 - 0
MJRefreshExample/MJRefreshExample.xcodeproj/project.pbxproj

@@ -462,6 +462,7 @@
 				GCC_PRECOMPILE_PREFIX_HEADER = YES;
 				GCC_PREFIX_HEADER = "MJRefreshExample/MJRefreshExample-Prefix.pch";
 				INFOPLIST_FILE = "MJRefreshExample/MJRefreshExample-Info.plist";
+				IPHONEOS_DEPLOYMENT_TARGET = 6.0;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				WRAPPER_EXTENSION = app;
 			};
@@ -475,6 +476,7 @@
 				GCC_PRECOMPILE_PREFIX_HEADER = YES;
 				GCC_PREFIX_HEADER = "MJRefreshExample/MJRefreshExample-Prefix.pch";
 				INFOPLIST_FILE = "MJRefreshExample/MJRefreshExample-Info.plist";
+				IPHONEOS_DEPLOYMENT_TARGET = 6.0;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				WRAPPER_EXTENSION = app;
 			};
@@ -539,6 +541,7 @@
 				2D9CAF9B192FAD750011F500 /* Release */,
 			);
 			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
 		};
 		2D9CAF9C192FAD750011F500 /* Build configuration list for PBXNativeTarget "MJRefreshExampleTests" */ = {
 			isa = XCConfigurationList;
@@ -547,6 +550,7 @@
 				2D9CAF9E192FAD750011F500 /* Release */,
 			);
 			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
 		};
 /* End XCConfigurationList section */
 	};

BIN
MJRefreshExample/MJRefreshExample.xcodeproj/project.xcworkspace/xcuserdata/mj.xcuserdatad/UserInterfaceState.xcuserstate


+ 83 - 46
MJRefreshExample/MJRefreshExample/Classes/Controller/MJCollectionViewController.m

@@ -10,21 +10,51 @@
  */
 NSString *const MJCollectionViewCellIdentifier = @"Cell";
 
+/**
+ *  随机颜色
+ */
+#define MJRandomColor [UIColor colorWithRed:arc4random_uniform(255)/255.0 green:arc4random_uniform(255)/255.0 blue:arc4random_uniform(255)/255.0 alpha:1]
+
 #import "MJCollectionViewController.h"
 #import "MJRefresh.h"
 
 @interface MJCollectionViewController () <MJRefreshBaseViewDelegate>
-{
-    NSMutableArray *_fakeColor;
-    MJRefreshHeaderView *_header;
-    MJRefreshFooterView *_footer;
-}
+/**
+ *  刷新控件
+ */
+@property (weak, nonatomic) MJRefreshFooterView *footer;
+@property (weak, nonatomic) MJRefreshHeaderView *header;
+/**
+ *  存放假数据
+ */
+@property (strong, nonatomic) NSMutableArray *fakeColors;
 @end
 
 @implementation MJCollectionViewController
 
+#pragma mark - 初始化
+/**
+ *  数据的懒加载
+ */
+- (NSMutableArray *)fakeColors
+{
+    if (_fakeColors == nil) {
+        self.fakeColors = [NSMutableArray array];
+        
+        for (int i = 0; i<5; i++) {
+            // 添加随机色
+            [self.fakeColors addObject:MJRandomColor];
+        }
+    }
+    return _fakeColors;
+}
+
+/**
+ *  初始化
+ */
 - (id)init
 {
+    // UICollectionViewFlowLayout的初始化(与刷新控件无关)
     UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
     layout.itemSize = CGSizeMake(80, 80);
     layout.sectionInset = UIEdgeInsetsMake(20, 20, 20, 20);
@@ -37,41 +67,51 @@ - (void)viewDidLoad
 {
     [super viewDidLoad];
     
-    // 1.注册
-    self.collectionView.backgroundColor = [UIColor whiteColor];
-    self.collectionView.alwaysBounceVertical = YES;
-    [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:MJCollectionViewCellIdentifier];
+    // 1.初始化collectionView
+    [self setupCollectionView];
     
-    // 2.假数据
-    _fakeColor = [NSMutableArray array];
-    for (int i = 0; i<5; i++) {
-        // 添加随机色
-        [_fakeColor addObject:[UIColor colorWithRed:arc4random_uniform(255)/255.0 green:arc4random_uniform(255)/255.0 blue:arc4random_uniform(255)/255.0 alpha:1]];
-    }
-    
-    // 3.集成刷新控件
-    // 3.1.下拉刷新
+    // 2.集成刷新控件
+    [self setupRefresh];
+}
+
+/**
+ *  集成刷新控件
+ */
+- (void)setupRefresh
+{
+    // 1.下拉刷新
     MJRefreshHeaderView *header = [MJRefreshHeaderView header];
     header.scrollView = self.collectionView;
     header.delegate = self;
-    // 自动刷新
+#warning 自动刷新(一进入程序就下拉刷新)
     [header beginRefreshing];
-    _header = header;
+    self.header = header;
     
-    // 3.2.上拉加载更多
+    // 2.上拉加载更多
     MJRefreshFooterView *footer = [MJRefreshFooterView footer];
     footer.scrollView = self.collectionView;
     footer.delegate = self;
-    _footer = footer;
+    self.footer = footer;
 }
 
-- (void)doneWithView:(MJRefreshBaseView *)refreshView
+/**
+ *  初始化collectionView
+ */
+- (void)setupCollectionView
 {
-    // 刷新表格
-    [self.collectionView reloadData];
-    
-    // (最好在刷新表格后调用)调用endRefreshing可以结束刷新状态
-    [refreshView endRefreshing];
+    self.collectionView.backgroundColor = [UIColor whiteColor];
+    self.collectionView.alwaysBounceVertical = YES;
+    [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:MJCollectionViewCellIdentifier];
+}
+
+/**
+ 为了保证内部不泄露,在dealloc中释放占用的内存
+ */
+- (void)dealloc
+{
+    NSLog(@"MJCollectionViewController--dealloc---");
+    [self.header free];
+    [self.footer free];
 }
 
 #pragma mark - 刷新控件的代理方法
@@ -82,12 +122,10 @@ - (void)refreshViewBeginRefreshing:(MJRefreshBaseView *)refreshView
     
     // 1.添加假数据
     for (int i = 0; i<5; i++) {
-        UIColor *color = [UIColor colorWithRed:arc4random_uniform(255)/255.0 green:arc4random_uniform(255)/255.0 blue:arc4random_uniform(255)/255.0 alpha:1];
-        
-        if ([refreshView isKindOfClass:[MJRefreshHeaderView class]]) {
-            [_fakeColor insertObject:color atIndex:0];
-        } else {
-            [_fakeColor addObject:color];
+        if ([refreshView isKindOfClass:[MJRefreshHeaderView class]]) { // 下拉刷新
+            [self.fakeColors insertObject:MJRandomColor atIndex:0];
+        } else { // 上拉加载更多
+            [self.fakeColors addObject:MJRandomColor];
         }
     }
     
@@ -101,6 +139,15 @@ - (void)refreshViewEndRefreshing:(MJRefreshBaseView *)refreshView
     NSLog(@"%@----刷新完毕", refreshView.class);
 }
 
+- (void)doneWithView:(MJRefreshBaseView *)refreshView
+{
+    // 刷新表格
+    [self.collectionView reloadData];
+    
+    // (最好在刷新表格后调用)调用endRefreshing可以结束刷新状态
+    [refreshView endRefreshing];
+}
+
 #pragma mark 监听刷新状态的改变
 - (void)refreshView:(MJRefreshBaseView *)refreshView stateChange:(MJRefreshState)state
 {
@@ -124,23 +171,13 @@ - (void)refreshView:(MJRefreshBaseView *)refreshView stateChange:(MJRefreshState
 #pragma mark - collection数据源代理
 - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
 {
-    return _fakeColor.count;
+    return self.fakeColors.count;
 }
 
 - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
 {
     UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:MJCollectionViewCellIdentifier forIndexPath:indexPath];
-    cell.backgroundColor = _fakeColor[indexPath.row];
+    cell.backgroundColor = self.fakeColors[indexPath.row];
     return cell;
 }
-
-/**
- 为了保证内部不泄露,在dealloc中释放占用的内存
- */
-- (void)dealloc
-{
-    NSLog(@"MJCollectionViewController--dealloc---");
-    [_header free];
-    [_footer free];
-}
 @end

+ 55 - 38
MJRefreshExample/MJRefreshExample/Classes/Controller/MJTableViewController.m

@@ -13,49 +13,76 @@
 
 NSString *const MJTableViewCellIdentifier = @"Cell";
 
+/**
+ *  随机数据
+ */
+#define MJRandomData [NSString stringWithFormat:@"随机数据---%d", arc4random_uniform(1000000)]
+
 @interface MJTableViewController ()
-{
-    NSMutableArray *_fakeData; // 假数据(只存放字符串)
-    
-    MJRefreshHeaderView *_header;
-    MJRefreshFooterView *_footer;
-}
+/**
+ *  刷新控件
+ */
+@property (weak, nonatomic) MJRefreshFooterView *footer;
+@property (weak, nonatomic) MJRefreshHeaderView *header;
+/**
+ *  存放假数据
+ */
+@property (strong, nonatomic) NSMutableArray *fakeData;
 @end
 
 @implementation MJTableViewController
+#pragma mark - 初始化
+/**
+ *  数据的懒加载
+ */
+- (NSMutableArray *)fakeData
+{
+    if (_fakeData == nil) {
+        self.fakeData = [NSMutableArray array];
+        
+        for (int i = 0; i<12; i++) {
+            [self.fakeData addObject:MJRandomData];
+        }
+    }
+    return _fakeData;
+}
 
 - (void)viewDidLoad
 {
     [super viewDidLoad];
     
-    // 1.注册
+    // 1.注册cell
     [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:MJTableViewCellIdentifier];
     
-    // 2.初始化假数据
-    _fakeData = [NSMutableArray array];
-    for (int i = 0; i<12; i++) {
-        int random = arc4random_uniform(1000000);
-        [_fakeData addObject:[NSString stringWithFormat:@"随机数据---%d", random]];
-    }
-    
-    // 3.集成刷新控件
-    // 3.1.下拉刷新
+    // 2.集成刷新控件
+    // 2.1.下拉刷新
     [self addHeader];
     
-    // 3.2.上拉加载更多
+    // 2.2.上拉加载更多
     [self addFooter];
 }
 
+/**
+ 为了保证内部不泄露,在dealloc中释放占用的内存
+ */
+- (void)dealloc
+{
+    NSLog(@"MJTableViewController--dealloc---");
+    [self.header free];
+    [self.footer free];
+}
+
 - (void)addFooter
 {
-    __unsafe_unretained MJTableViewController *vc = self;
     MJRefreshFooterView *footer = [MJRefreshFooterView footer];
     footer.scrollView = self.tableView;
+    
+    __unsafe_unretained MJTableViewController *vc = self;
+    // 进入刷新状态就会调用beginRefreshingBlock
     footer.beginRefreshingBlock = ^(MJRefreshBaseView *refreshView) {
         // 增加5条假数据
         for (int i = 0; i<5; i++) {
-            int random = arc4random_uniform(1000000);
-            [vc->_fakeData addObject:[NSString stringWithFormat:@"随机数据---%d", random]];
+            [vc.fakeData addObject:MJRandomData];
         }
         
         // 模拟延迟加载数据,因此2秒后才调用)
@@ -64,22 +91,21 @@ - (void)addFooter
         
         NSLog(@"%@----开始进入刷新状态", refreshView.class);
     };
-    _footer = footer;
+    self.footer = footer;
 }
 
 - (void)addHeader
 {
-    __unsafe_unretained MJTableViewController *vc = self;
-    
     MJRefreshHeaderView *header = [MJRefreshHeaderView header];
     header.scrollView = self.tableView;
+    
+    __unsafe_unretained MJTableViewController *vc = self;
     header.beginRefreshingBlock = ^(MJRefreshBaseView *refreshView) {
         // 进入刷新状态就会回调这个Block
         
         // 增加5条假数据
         for (int i = 0; i<5; i++) {
-            int random = arc4random_uniform(1000000);
-            [vc->_fakeData insertObject:[NSString stringWithFormat:@"随机数据---%d", random] atIndex:0];
+            [vc.fakeData insertObject:MJRandomData atIndex:0];
         }
         
         // 模拟延迟加载数据,因此2秒后才调用)
@@ -110,8 +136,9 @@ - (void)addHeader
                 break;
         }
     };
+#warning 自动刷新(一进入程序就下拉刷新)
     [header beginRefreshing];
-    _header = header;
+    self.header = header;
 }
 
 - (void)doneWithView:(MJRefreshBaseView *)refreshView
@@ -125,25 +152,15 @@ - (void)doneWithView:(MJRefreshBaseView *)refreshView
 #pragma mark - Table view data source
 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
 {
-    return _fakeData.count;
+    return self.fakeData.count;
 }
 
 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
 {
     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MJTableViewCellIdentifier forIndexPath:indexPath];
     
-    cell.textLabel.text = _fakeData[indexPath.row];
+    cell.textLabel.text = self.fakeData[indexPath.row];
     return cell;
 }
 
-/**
- 为了保证内部不泄露,在dealloc中释放占用的内存
- */
-- (void)dealloc
-{
-    NSLog(@"MJTableViewController--dealloc---");
-    [_header free];
-    [_footer free];
-}
-
 @end

+ 60 - 46
MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshBaseView.h

@@ -7,10 +7,9 @@
 
 #import <UIKit/UIKit.h>
 
-/**
- 枚举
- */
-// 控件的刷新状态
+@class MJRefreshBaseView;
+
+#pragma mark - 控件的刷新状态
 typedef enum {
 	MJRefreshStatePulling = 1, // 松开就可以进行刷新的状态
 	MJRefreshStateNormal = 2, // 普通状态
@@ -18,22 +17,15 @@ typedef enum {
     MJRefreshStateWillRefreshing = 4
 } MJRefreshState;
 
-// 控件的类型
+#pragma mark - 控件的类型
 typedef enum {
     MJRefreshViewTypeHeader = -1, // 头部控件
     MJRefreshViewTypeFooter = 1 // 尾部控件
 } MJRefreshViewType;
 
-@class MJRefreshBaseView;
-
-/**
- 回调的Block定义
- */
-// 开始进入刷新状态就会调用
+#pragma mark - 回调的Block定义
 typedef void (^BeginRefreshingBlock)(MJRefreshBaseView *refreshView);
-// 刷新完毕就会调用
 typedef void (^EndRefreshingBlock)(MJRefreshBaseView *refreshView);
-// 刷新状态变更就会调用
 typedef void (^RefreshStateChangeBlock)(MJRefreshBaseView *refreshView, MJRefreshState state);
 
 /**
@@ -41,11 +33,24 @@ typedef void (^RefreshStateChangeBlock)(MJRefreshBaseView *refreshView, MJRefres
  */
 @protocol MJRefreshBaseViewDelegate <NSObject>
 @optional
-// 开始进入刷新状态就会调用
+/**
+ *  开始进入刷新状态就会调用
+ *
+ *  @param refreshView 刷新控件
+ */
 - (void)refreshViewBeginRefreshing:(MJRefreshBaseView *)refreshView;
-// 刷新完毕就会调用
+/**
+ *  刷新完毕就会调用
+ *
+ *  @param refreshView 刷新控件
+ */
 - (void)refreshViewEndRefreshing:(MJRefreshBaseView *)refreshView;
-// 刷新状态变更就会调用
+/**
+ *  刷新状态变更就会调用
+ *
+ *  @param refreshView 刷新控件
+ *  @param state       刷新控件的状态
+ */
 - (void)refreshView:(MJRefreshBaseView *)refreshView stateChange:(MJRefreshState)state;
 @end
 
@@ -53,53 +58,62 @@ typedef void (^RefreshStateChangeBlock)(MJRefreshBaseView *refreshView, MJRefres
  类的声明
  */
 @interface MJRefreshBaseView : UIView
-{
-    // 父控件一开始的contentInset
-    UIEdgeInsets _scrollViewInitInset;
-    // 父控件
-    __weak UIScrollView *_scrollView;
-    
-    // 子控件
-    __weak UILabel *_lastUpdateTimeLabel;
-	__weak UILabel *_statusLabel;
-    __weak UIImageView *_arrowImage;
-	__weak UIActivityIndicatorView *_activityView;
-    
-    // 状态
-    MJRefreshState _state;
-}
-
-// 构造方法
+/**
+ *  构造方法
+ */
 - (instancetype)initWithScrollView:(UIScrollView *)scrollView;
-// 设置要显示的父控件
+
+/**
+ *  设置要显示的父控件
+ */
 @property (nonatomic, weak) UIScrollView *scrollView;
 
-// 内部的控件
+#pragma mark - 内部的控件
 @property (nonatomic, weak, readonly) UILabel *lastUpdateTimeLabel;
 @property (nonatomic, weak, readonly) UILabel *statusLabel;
 @property (nonatomic, weak, readonly) UIImageView *arrowImage;
+@property (nonatomic, weak, readonly) UIActivityIndicatorView *activityView;
+@property (nonatomic, assign, readonly) UIEdgeInsets scrollViewInitInset;
 
-// Block回调
+#pragma mark - 监听相关
+/**
+ *  开始进入刷新状态就会调用
+ */
 @property (nonatomic, copy) BeginRefreshingBlock beginRefreshingBlock;
+/**
+ *  刷新完毕就会调用
+ */
 @property (nonatomic, copy) RefreshStateChangeBlock refreshStateChangeBlock;
+/**
+ *  刷新状态变更就会调用
+ */
 @property (nonatomic, copy) EndRefreshingBlock endStateChangeBlock;
-// 代理
+
+/**
+ *  代理
+ */
 @property (nonatomic, weak) id<MJRefreshBaseViewDelegate> delegate;
 
-// 是否正在刷新
+#pragma mark - 刷新相关
+/**
+ *  是否正在刷新
+ */
 @property (nonatomic, readonly, getter=isRefreshing) BOOL refreshing;
-// 开始刷新
+/**
+ *  开始刷新
+ */
 - (void)beginRefreshing;
-// 结束刷新
+/**
+ *  结束刷新
+ */
 - (void)endRefreshing;
-// 不静止地结束刷新
-//- (void)endRefreshingWithoutIdle;
-// 结束使用、释放资源
-- (void)free;
 
 /**
- 交给子类去实现 和 调用
+ *  结束使用、释放资源
  */
-- (void)setState:(MJRefreshState)state;
+- (void)free;
+
+#pragma mark - 交给子类去实现 和 调用
+@property (assign, nonatomic) MJRefreshState state;
 - (int)totalDataCountInScrollView;
 @end

+ 85 - 88
MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshBaseView.m

@@ -10,9 +10,7 @@
 #import "MJRefreshConst.h"
 
 @interface  MJRefreshBaseView()
-{
-    BOOL _hasInitInset;
-}
+@property (assign, nonatomic) BOOL hasInitInset;
 /**
  交给子类去实现
  */
@@ -23,8 +21,12 @@ - (MJRefreshViewType)viewType;
 @end
 
 @implementation MJRefreshBaseView
-
-#pragma mark 创建一个UILabel
+#pragma mark - 初始化方法
+/**
+ *  创建一个UILabel
+ *
+ *  @param size 字体大小
+ */
 - (UILabel *)labelWithFontSize:(CGFloat)size
 {
     UILabel *label = [[UILabel alloc] init];
@@ -36,7 +38,6 @@ - (UILabel *)labelWithFontSize:(CGFloat)size
     return label;
 }
 
-#pragma mark - 初始化方法
 - (instancetype)initWithScrollView:(UIScrollView *)scrollView
 {
     if (self = [super init]) {
@@ -49,20 +50,24 @@ - (void)layoutSubviews
 {
     [super layoutSubviews];
     
-    if (!_hasInitInset) {
-        _scrollViewInitInset = _scrollView.contentInset;
-    
+    if (!self.hasInitInset) { // 记录scrollView刚开始的contentInset
+        _scrollViewInitInset = self.scrollView.contentInset;
+        
+        // 监听
         [self observeValueForKeyPath:MJRefreshContentSize ofObject:nil change:nil context:nil];
         
-        _hasInitInset = YES;
+        self.hasInitInset = YES;
         
-        if (_state == MJRefreshStateWillRefreshing) {
+        // 进入刷新状态
+        if (self.state == MJRefreshStateWillRefreshing) {
             [self setState:MJRefreshStateRefreshing];
         }
     }
 }
 
-#pragma mark 构造方法
+/**
+ *  构造方法
+ */
 - (instancetype)initWithFrame:(CGRect)frame {
     if (self = [super initWithFrame:frame]) {
         // 1.自己的属性
@@ -76,7 +81,7 @@ - (instancetype)initWithFrame:(CGRect)frame {
         [self addSubview:_statusLabel = [self labelWithFontSize:13]];
         
         // 4.箭头图片
-        UIImageView *arrowImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:kSrcName(@"arrow.png")]];
+        UIImageView *arrowImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:MJRefreshSrcName(@"arrow.png")]];
         arrowImage.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
         [self addSubview:_arrowImage = arrowImage];
         
@@ -87,12 +92,14 @@ - (instancetype)initWithFrame:(CGRect)frame {
         [self addSubview:_activityView = activityView];
         
         // 6.设置默认状态
-        [self setState:MJRefreshStateNormal];
+        self.state = MJRefreshStateNormal;
     }
     return self;
 }
 
-#pragma mark 设置frame
+/**
+ *  设置frame
+ */
 - (void)setFrame:(CGRect)frame
 {
     frame.size.height = MJRefreshViewHeight;
@@ -100,25 +107,25 @@ - (void)setFrame:(CGRect)frame
     
     CGFloat w = frame.size.width;
     CGFloat h = frame.size.height;
-    if (w == 0 || _arrowImage.center.y == h * 0.5) return;
+    if (w == 0 || self.arrowImage.center.y == h * 0.5) return;
     
     CGFloat statusX = 0;
     CGFloat statusY = 5;
     CGFloat statusHeight = 20;
     CGFloat statusWidth = w;
     // 1.状态标签
-    _statusLabel.frame = CGRectMake(statusX, statusY, statusWidth, statusHeight);
-
+    self.statusLabel.frame = CGRectMake(statusX, statusY, statusWidth, statusHeight);
+    
     // 2.时间标签
     CGFloat lastUpdateY = statusY + statusHeight + 5;
-    _lastUpdateTimeLabel.frame = CGRectMake(statusX, lastUpdateY, statusWidth, statusHeight);
+    self.lastUpdateTimeLabel.frame = CGRectMake(statusX, lastUpdateY, statusWidth, statusHeight);
     
     // 3.箭头
     CGFloat arrowX = w * 0.5 - 100;
-    _arrowImage.center = CGPointMake(arrowX, h * 0.5);
+    self.arrowImage.center = CGPointMake(arrowX, h * 0.5);
     
     // 4.指示器
-    _activityView.center = _arrowImage.center;
+    self.activityView.center = _arrowImage.center;
 }
 
 - (void)setBounds:(CGRect)bounds
@@ -128,17 +135,19 @@ - (void)setBounds:(CGRect)bounds
 }
 
 #pragma mark - UIScrollView相关
-#pragma mark 设置UIScrollView
+/**
+ *  设置UIScrollView
+*/
 - (void)setScrollView:(UIScrollView *)scrollView
 {
     // 移除之前的监听器
-    [_scrollView removeObserver:self forKeyPath:MJRefreshContentOffset context:nil];
+    [self.scrollView removeObserver:self forKeyPath:MJRefreshContentOffset context:nil];
     // 监听contentOffset
     [scrollView addObserver:self forKeyPath:MJRefreshContentOffset options:NSKeyValueObservingOptionNew context:nil];
     
     // 设置scrollView
     _scrollView = scrollView;
-    [_scrollView addSubview:self];
+    [scrollView addSubview:self];
 }
 
 #pragma mark 监听UIScrollView的contentOffset属性
@@ -147,86 +156,78 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
     if (![MJRefreshContentOffset isEqualToString:keyPath]) return;
     
     if (!self.userInteractionEnabled || self.alpha <= 0.01 || self.hidden
-        || _state == MJRefreshStateRefreshing) return;
+        || self.state == MJRefreshStateRefreshing) return;
     
     // scrollView所滚动的Y值 * 控件的类型(头部控件是-1,尾部控件是1)
-    CGFloat offsetY = _scrollView.contentOffset.y * self.viewType;
+    CGFloat offsetY = self.scrollView.contentOffset.y * self.viewType;
     CGFloat validY = self.validY;
     if (offsetY <= validY) return;
     
-    if (_scrollView.isDragging) {
+    if (self.scrollView.isDragging) {
         CGFloat validOffsetY = validY + MJRefreshViewHeight;
-        if (_state == MJRefreshStatePulling && offsetY <= validOffsetY) {
+        if (self.state == MJRefreshStatePulling && offsetY <= validOffsetY) {
             // 转为普通状态
-            [self setState:MJRefreshStateNormal];
-            // 通知代理
-            if ([_delegate respondsToSelector:@selector(refreshView:stateChange:)]) {
-                [_delegate refreshView:self stateChange:MJRefreshStateNormal];
-            }
-            
-            // 回调
-            if (_refreshStateChangeBlock) {
-                _refreshStateChangeBlock(self, MJRefreshStateNormal);
-            }
-        } else if (_state == MJRefreshStateNormal && offsetY > validOffsetY) {
+            self.state = MJRefreshStateNormal;
+            [self notifyStateChange];
+        } else if (self.state == MJRefreshStateNormal && offsetY > validOffsetY) {
             // 转为即将刷新状态
-            [self setState:MJRefreshStatePulling];
-            // 通知代理
-            if ([_delegate respondsToSelector:@selector(refreshView:stateChange:)]) {
-                [_delegate refreshView:self stateChange:MJRefreshStatePulling];
-            }
-            
-            // 回调
-            if (_refreshStateChangeBlock) {
-                _refreshStateChangeBlock(self, MJRefreshStatePulling);
-            }
+            self.state = MJRefreshStatePulling;
+            [self notifyStateChange];
         }
     } else { // 即将刷新 && 手松开
-        if (_state == MJRefreshStatePulling) {
+        if (self.state == MJRefreshStatePulling) {
             // 开始刷新
-            [self setState:MJRefreshStateRefreshing];
-            // 通知代理
-            if ([_delegate respondsToSelector:@selector(refreshView:stateChange:)]) {
-                [_delegate refreshView:self stateChange:MJRefreshStateRefreshing];
-            }
-            
-            // 回调
-            if (_refreshStateChangeBlock) {
-                _refreshStateChangeBlock(self, MJRefreshStateRefreshing);
-            }
+            self.state = MJRefreshStateRefreshing;
+            [self notifyStateChange];
         }
     }
 }
 
+/**
+ *  通知状态改变
+ */
+- (void)notifyStateChange
+{
+    // 通知代理
+    if ([self.delegate respondsToSelector:@selector(refreshView:stateChange:)]) {
+        [self.delegate refreshView:self stateChange:self.state];
+    }
+    
+    // 回调
+    if (self.refreshStateChangeBlock) {
+        self.refreshStateChangeBlock(self, self.state);
+    }
+}
+
 #pragma mark 设置状态
 - (void)setState:(MJRefreshState)state
 {
-    if (_state != MJRefreshStateRefreshing) {
+    if (self.state != MJRefreshStateRefreshing) {
         // 存储当前的contentInset
-        _scrollViewInitInset = _scrollView.contentInset;
+        _scrollViewInitInset = self.scrollView.contentInset;
     }
     
     // 1.一样的就直接返回
-    if (_state == state) return;
+    if (self.state == state) return;
     
     // 2.根据状态执行不同的操作
     switch (state) {
 		case MJRefreshStateNormal: // 普通状态
             // 显示箭头
-            _arrowImage.hidden = NO;
+            self.arrowImage.hidden = NO;
             // 停止转圈圈
-			[_activityView stopAnimating];
+			[self.activityView stopAnimating];
             
             // 说明是刚刷新完毕 回到 普通状态的
-            if (MJRefreshStateRefreshing == _state) {
+            if (MJRefreshStateRefreshing == self.state) {
                 // 通知代理
-                if ([_delegate respondsToSelector:@selector(refreshViewEndRefreshing:)]) {
-                    [_delegate refreshViewEndRefreshing:self];
+                if ([self.delegate respondsToSelector:@selector(refreshViewEndRefreshing:)]) {
+                    [self.delegate refreshViewEndRefreshing:self];
                 }
                 
                 // 回调
-                if (_endStateChangeBlock) {
-                    _endStateChangeBlock(self);
+                if (self.endStateChangeBlock) {
+                    self.endStateChangeBlock(self);
                 }
             }
             
@@ -237,19 +238,19 @@ - (void)setState:(MJRefreshState)state
             
 		case MJRefreshStateRefreshing:
             // 开始转圈圈
-			[_activityView startAnimating];
+			[self.activityView startAnimating];
             // 隐藏箭头
-			_arrowImage.hidden = YES;
-            _arrowImage.transform = CGAffineTransformIdentity;
+			self.arrowImage.hidden = YES;
+            self.arrowImage.transform = CGAffineTransformIdentity;
             
             // 通知代理
-            if ([_delegate respondsToSelector:@selector(refreshViewBeginRefreshing:)]) {
-                [_delegate refreshViewBeginRefreshing:self];
+            if ([self.delegate respondsToSelector:@selector(refreshViewBeginRefreshing:)]) {
+                [self.delegate refreshViewBeginRefreshing:self];
             }
             
             // 回调
-            if (_beginRefreshingBlock) {
-                _beginRefreshingBlock(self);
+            if (self.beginRefreshingBlock) {
+                self.beginRefreshingBlock(self);
             }
 			break;
         default:
@@ -264,13 +265,13 @@ - (void)setState:(MJRefreshState)state
 #pragma mark 是否正在刷新
 - (BOOL)isRefreshing
 {
-    return MJRefreshStateRefreshing == _state;
+    return MJRefreshStateRefreshing == self.state;
 }
 #pragma mark 开始刷新
 - (void)beginRefreshing
 {
     if (self.window) {
-        [self setState:MJRefreshStateRefreshing];
+        self.state = MJRefreshStateRefreshing;
     } else {
         _state = MJRefreshStateWillRefreshing;
     }
@@ -281,7 +282,7 @@ - (void)endRefreshing
     double delayInSeconds = 0.3;
     dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
     dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
-        [self setState:MJRefreshStateNormal];
+        self.state = MJRefreshStateNormal;
     });
 }
 
@@ -290,20 +291,16 @@ - (CGFloat)validY { return 0;}
 - (MJRefreshViewType)viewType {return MJRefreshViewTypeHeader;}
 - (void)free
 {
-    [_scrollView removeObserver:self forKeyPath:MJRefreshContentOffset];
+    [self.scrollView removeObserver:self forKeyPath:MJRefreshContentOffset];
 }
 - (void)removeFromSuperview
 {
-    [self free];
-    _scrollView = nil;
+    MJLog(@"removeFromSuperview");
+//    [self free];
+    self.scrollView = nil;
     [super removeFromSuperview];
 }
 
-- (void)endRefreshingWithoutIdle
-{
-    [self endRefreshing];
-}
-
 - (int)totalDataCountInScrollView
 {
     int totalCount = 0;

+ 1 - 1
MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshConst.h

@@ -19,7 +19,7 @@ extern const CGFloat MJRefreshViewHeight;
 extern const CGFloat MJRefreshAnimationDuration;
 
 extern NSString *const MJRefreshBundleName;
-#define kSrcName(file) [MJRefreshBundleName stringByAppendingPathComponent:file]
+#define MJRefreshSrcName(file) [MJRefreshBundleName stringByAppendingPathComponent:file]
 
 extern NSString *const MJRefreshFooterPullToRefresh;
 extern NSString *const MJRefreshFooterReleaseToRefresh;

+ 35 - 41
MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshFooterView.m

@@ -10,12 +10,7 @@
 #import "MJRefreshConst.h"
 
 @interface MJRefreshFooterView()
-//{
-//    BOOL _withoutIdle;
-//}
-{
-    int _lastRefreshCount;
-}
+@property (assign, nonatomic) int lastRefreshCount;
 @end
 
 @implementation MJRefreshFooterView
@@ -29,8 +24,7 @@ + (instancetype)footer
 - (instancetype)initWithFrame:(CGRect)frame {
     if (self = [super initWithFrame: frame]) {
         // 移除刷新时间
-		[_lastUpdateTimeLabel removeFromSuperview];
-        _lastUpdateTimeLabel = nil;
+		[self.lastUpdateTimeLabel removeFromSuperview];
     }
     return self;
 }
@@ -40,9 +34,9 @@ - (void)setFrame:(CGRect)frame
     [super setFrame:frame];
     
     CGFloat h = frame.size.height;
-    if (_statusLabel.center.y != h * 0.5) {
-        CGFloat w = frame.size.width;
-        _statusLabel.center = CGPointMake(w * 0.5, h * 0.5);
+    if (self.statusLabel.center.y != h * 0.5) {
+        CGFloat w = self.frame.size.width;
+        self.statusLabel.center = CGPointMake(w * 0.5, h * 0.5);
     }
 }
 
@@ -51,7 +45,7 @@ - (void)setFrame:(CGRect)frame
 - (void)setScrollView:(UIScrollView *)scrollView
 {
     // 1.移除以前的监听器
-    [_scrollView removeObserver:self forKeyPath:MJRefreshContentSize context:nil];
+    [self.scrollView removeObserver:self forKeyPath:MJRefreshContentSize context:nil];
     // 2.监听contentSize
     [scrollView addObserver:self forKeyPath:MJRefreshContentSize options:NSKeyValueObservingOptionNew context:nil];
     
@@ -78,20 +72,20 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
 - (void)adjustFrame
 {
     // 内容的高度
-    CGFloat contentHeight = _scrollView.contentSize.height;
+    CGFloat contentHeight = self.scrollView.contentSize.height;
     // 表格的高度
-    CGFloat scrollHeight = _scrollView.frame.size.height - _scrollViewInitInset.top - _scrollViewInitInset.bottom;
+    CGFloat scrollHeight = self.scrollView.frame.size.height - self.scrollViewInitInset.top - self.scrollViewInitInset.bottom;
     CGFloat y = MAX(contentHeight, scrollHeight);
     // 设置边框
-    self.frame = CGRectMake(0, y, _scrollView.frame.size.width, MJRefreshViewHeight);
+    self.frame = CGRectMake(0, y, self.scrollView.frame.size.width, MJRefreshViewHeight);
 }
 
 #pragma mark - 状态相关
 #pragma mark 设置状态
 - (void)setState:(MJRefreshState)state
 {
-    if (_state == state) return;
-    MJRefreshState oldState = _state;
+    if (self.state == state) return;
+    MJRefreshState oldState = self.state;
     
     [super setState:state];
     
@@ -99,20 +93,20 @@ - (void)setState:(MJRefreshState)state
     {
 		case MJRefreshStatePulling:
         {
-            _statusLabel.text = MJRefreshFooterReleaseToRefresh;
+            self.statusLabel.text = MJRefreshFooterReleaseToRefresh;
             
             [UIView animateWithDuration:MJRefreshAnimationDuration animations:^{
-                _arrowImage.transform = CGAffineTransformIdentity;
-                UIEdgeInsets inset = _scrollView.contentInset;
-                inset.bottom = _scrollViewInitInset.bottom;
-                _scrollView.contentInset = inset;
+                self.arrowImage.transform = CGAffineTransformIdentity;
+                UIEdgeInsets inset = self.scrollView.contentInset;
+                inset.bottom = self.scrollViewInitInset.bottom;
+                self.scrollView.contentInset = inset;
             }];
 			break;
         }
             
 		case MJRefreshStateNormal:
         {
-            _statusLabel.text = MJRefreshFooterPullToRefresh;
+            self.statusLabel.text = MJRefreshFooterPullToRefresh;
             
             // 刚刷新完毕
             CGFloat animDuration = MJRefreshAnimationDuration;
@@ -120,20 +114,20 @@ - (void)setState:(MJRefreshState)state
             CGPoint tempOffset;
             
             int currentCount = [self totalDataCountInScrollView];
-            if (MJRefreshStateRefreshing == oldState && deltaH > 0 && currentCount != _lastRefreshCount) {
-                tempOffset = _scrollView.contentOffset;
+            if (MJRefreshStateRefreshing == oldState && deltaH > 0 && currentCount != self.lastRefreshCount) {
+                tempOffset = self.scrollView.contentOffset;
                 animDuration = 0;
             }
             
             [UIView animateWithDuration:animDuration animations:^{
-                _arrowImage.transform = CGAffineTransformMakeRotation(M_PI);
-                UIEdgeInsets inset = _scrollView.contentInset;
-                inset.bottom = _scrollViewInitInset.bottom;
-                _scrollView.contentInset = inset;
+                self.arrowImage.transform = CGAffineTransformMakeRotation(M_PI);
+                UIEdgeInsets inset = self.scrollView.contentInset;
+                inset.bottom = self.scrollViewInitInset.bottom;
+                self.scrollView.contentInset = inset;
             }];
             
             if (animDuration == 0) {
-                _scrollView.contentOffset = tempOffset;
+                self.scrollView.contentOffset = tempOffset;
             }
 			break;
         }
@@ -141,19 +135,19 @@ - (void)setState:(MJRefreshState)state
         case MJRefreshStateRefreshing:
         {
             // 记录刷新前的数量
-            _lastRefreshCount = [self totalDataCountInScrollView];
+            self.lastRefreshCount = [self totalDataCountInScrollView];
             
-            _statusLabel.text = MJRefreshFooterRefreshing;
-            _arrowImage.transform = CGAffineTransformMakeRotation(M_PI);
+            self.statusLabel.text = MJRefreshFooterRefreshing;
+            self.arrowImage.transform = CGAffineTransformMakeRotation(M_PI);
             [UIView animateWithDuration:MJRefreshAnimationDuration animations:^{
-                UIEdgeInsets inset = _scrollView.contentInset;
-                CGFloat bottom = MJRefreshViewHeight + _scrollViewInitInset.bottom;
+                UIEdgeInsets inset = self.scrollView.contentInset;
+                CGFloat bottom = MJRefreshViewHeight + self.scrollViewInitInset.bottom;
                 CGFloat deltaH = [self contentBreakView];
                 if (deltaH < 0) { // 如果内容高度小于view的高度
                     bottom -= deltaH;
                 }
                 inset.bottom = bottom;
-                _scrollView.contentInset = inset;
+                self.scrollView.contentInset = inset;
             }];
 			break;
         }
@@ -173,8 +167,8 @@ - (void)setState:(MJRefreshState)state
 #pragma mark 获得scrollView的内容 超出 view 的高度
 - (CGFloat)contentBreakView
 {
-    CGFloat h = _scrollView.frame.size.height - _scrollViewInitInset.bottom - _scrollViewInitInset.top;
-    return _scrollView.contentSize.height - h;
+    CGFloat h = self.scrollView.frame.size.height - self.scrollViewInitInset.bottom - self.scrollViewInitInset.top;
+    return self.scrollView.contentSize.height - h;
 }
 
 #pragma mark - 在父类中用得上
@@ -183,9 +177,9 @@ - (CGFloat)validY
 {
     CGFloat deltaH = [self contentBreakView];
     if (deltaH > 0) {
-        return deltaH -_scrollViewInitInset.top;
+        return deltaH - self.scrollViewInitInset.top;
     } else {
-        return -_scrollViewInitInset.top;
+        return - self.scrollViewInitInset.top;
     }
 }
 
@@ -198,6 +192,6 @@ - (int)viewType
 - (void)free
 {
     [super free];
-    [_scrollView removeObserver:self forKeyPath:MJRefreshContentSize];
+    [self.scrollView removeObserver:self forKeyPath:MJRefreshContentSize];
 }
 @end

+ 23 - 23
MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshHeaderView.m

@@ -41,7 +41,7 @@ - (void)setLastUpdateTime:(NSDate *)lastUpdateTime
     _lastUpdateTime = lastUpdateTime;
     
     // 1.归档
-    [[NSUserDefaults standardUserDefaults] setObject:_lastUpdateTime forKey:MJRefreshHeaderTimeKey];
+    [[NSUserDefaults standardUserDefaults] setObject:lastUpdateTime forKey:MJRefreshHeaderTimeKey];
     [[NSUserDefaults standardUserDefaults] synchronize];
     
     // 2.更新时间
@@ -51,7 +51,7 @@ - (void)setLastUpdateTime:(NSDate *)lastUpdateTime
 #pragma mark 更新时间字符串
 - (void)updateTimeLabel
 {
-    if (!_lastUpdateTime) return;
+    if (!self.lastUpdateTime) return;
     
     // 1.获得年月日
     NSCalendar *calendar = [NSCalendar currentCalendar];
@@ -68,20 +68,20 @@ - (void)updateTimeLabel
     } else {
         formatter.dateFormat = @"yyyy-MM-dd HH:mm";
     }
-    NSString *time = [formatter stringFromDate:_lastUpdateTime];
+    NSString *time = [formatter stringFromDate:self.lastUpdateTime];
     
     // 3.显示日期
-    _lastUpdateTimeLabel.text = [NSString stringWithFormat:@"最后更新:%@", time];
+    self.lastUpdateTimeLabel.text = [NSString stringWithFormat:@"最后更新:%@", time];
 }
 
 #pragma mark 设置状态
 - (void)setState:(MJRefreshState)state
 {
     // 1.一样的就直接返回
-    if (_state == state) return;
+    if (self.state == state) return;
     
     // 2.保存旧状态
-    MJRefreshState oldState = _state;
+    MJRefreshState oldState = self.state;
     
     // 3.调用父类方法
     [super setState:state];
@@ -91,13 +91,13 @@ - (void)setState:(MJRefreshState)state
 		case MJRefreshStatePulling: // 松开可立即刷新
         {
             // 设置文字
-            _statusLabel.text = MJRefreshHeaderReleaseToRefresh;
+            self.statusLabel.text = MJRefreshHeaderReleaseToRefresh;
             // 执行动画
             [UIView animateWithDuration:MJRefreshAnimationDuration animations:^{
-                _arrowImage.transform = CGAffineTransformMakeRotation(M_PI);
-                UIEdgeInsets inset = _scrollView.contentInset;
-                inset.top = _scrollViewInitInset.top;
-                _scrollView.contentInset = inset;
+                self.arrowImage.transform = CGAffineTransformMakeRotation(M_PI);
+                UIEdgeInsets inset = self.scrollView.contentInset;
+                inset.top = self.scrollViewInitInset.top;
+                self.scrollView.contentInset = inset;
             }];
 			break;
         }
@@ -105,13 +105,13 @@ - (void)setState:(MJRefreshState)state
 		case MJRefreshStateNormal: // 下拉可以刷新
         {
             // 设置文字
-			_statusLabel.text = MJRefreshHeaderPullToRefresh;
+			self.statusLabel.text = MJRefreshHeaderPullToRefresh;
             // 执行动画
             [UIView animateWithDuration:MJRefreshAnimationDuration animations:^{
-                _arrowImage.transform = CGAffineTransformIdentity;
-                UIEdgeInsets inset = _scrollView.contentInset;
-                inset.top = _scrollViewInitInset.top;
-                _scrollView.contentInset = inset;
+                self.arrowImage.transform = CGAffineTransformIdentity;
+                UIEdgeInsets inset = self.scrollView.contentInset;
+                inset.top = self.scrollViewInitInset.top;
+                self.scrollView.contentInset = inset;
             }];
             
             // 刷新完毕
@@ -125,16 +125,16 @@ - (void)setState:(MJRefreshState)state
 		case MJRefreshStateRefreshing: // 正在刷新中
         {
             // 设置文字
-            _statusLabel.text = MJRefreshHeaderRefreshing;
+            self.statusLabel.text = MJRefreshHeaderRefreshing;
             // 执行动画
             [UIView animateWithDuration:MJRefreshAnimationDuration animations:^{
-                _arrowImage.transform = CGAffineTransformIdentity;
+                self.arrowImage.transform = CGAffineTransformIdentity;
                 // 1.增加65的滚动区域
-                UIEdgeInsets inset = _scrollView.contentInset;
-                inset.top = _scrollViewInitInset.top + MJRefreshViewHeight;
-                _scrollView.contentInset = inset;
+                UIEdgeInsets inset = self.scrollView.contentInset;
+                inset.top = self.scrollViewInitInset.top + MJRefreshViewHeight;
+                self.scrollView.contentInset = inset;
                 // 2.设置滚动位置
-                _scrollView.contentOffset = CGPointMake(0, - _scrollViewInitInset.top - MJRefreshViewHeight);
+                self.scrollView.contentOffset = CGPointMake(0, - self.scrollViewInitInset.top - MJRefreshViewHeight);
             }];
 			break;
         }
@@ -148,7 +148,7 @@ - (void)setState:(MJRefreshState)state
 // 合理的Y值(刚好看到下拉刷新控件时的contentOffset.y,取相反数)
 - (CGFloat)validY
 {
-    return _scrollViewInitInset.top;
+    return self.scrollViewInitInset.top;
 }
 
 // view的类型