在寫這篇文章之前,我一直很糾結,到底要不要寫呢?任何一個寫iOS的程式員或者稱為程式設計者,都應該對MJRefresh熟悉的不能再熟悉了。幾乎每個人都用過,也知道如何使用,那麼我又何必再在這裡寫下這篇文章呢?回答這個問題之前,我想問幾個問題:
1:MJRefresh 與header和Footer相關的類有幾個?
2:MJRefresh 中不同的Footer有什麼差別?
3:MJRefresh 中不同的Header有什麼差別?
4:如何自定義Footer和Header?
如果你都能回答上來,那麼這篇文章可以不用往下看了。如果有些許疑問,那麼希望這篇淺顯的文章可以給您提供些許幫助。
(MJRefresh下載下傳位址:
https://github.com/CoderMJLee/MJRefresh.git)
一、MJRefresh目錄簡介
首先讓我們浏覽下,MJRefresh都有哪些類檔案。
image.png
這些檔案大緻分為四類:
輔助類(擴充類)
資源類(圖檔等)
自定義類(custom)
基礎類 (base)
繼續展開看:
Custom檔案夾:
這裡又包括兩個檔案夾,Header和Footer,我們經常使用的也是這個裡面的一些類檔案。
繼續展開:
我們發現,這個檔案夾中,Header有三種,Footer有六種。看到這裡的時候,想必大家跟我一樣有個疑問:這麼多種有什麼差別呢?
先把疑問留在這裡,我們繼續往下看。
Base檔案夾:
再次發現,base檔案夾裡還有很多個Header和Footer,這是怎麼回事呢?
二、類之間的關系圖
看完這個圖之後,是不是基本理清楚了他們之間的關系呢?有沒有又發現個小問題呢?
會回彈的重新整理控件和會自動重新整理的上拉重新整理控件又是什麼呢?
小練習:
看完上面的目錄介紹以及結構圖之後,如果覺得自己了解了或者有印象但不清晰的話,建議自己畫一幅MJRefresh的主要重新整理類之間關系圖。下面是我自己畫的:
如果你自己不參考任何東西就可以畫出來的話,說明你真的對他們之間的關系弄清楚了。
三、詳細介紹 Header和Footer
1、Header
-
MJRefreshHeader
效果:
MJRefreshHeader 沒有文字和提示,不能彈回去,隻能重新整理一次。
用法:
-(void)MJRefreshHeader_Default{
__weak DownDefaultController * weakSelf = self;
self.tableView.mj_header = [MJRefreshHeader headerWithRefreshingBlock:^{
[weakSelf loadData];
[weakSelf.tableView reloadData];
}];
}
運作結果:
正常狀态:
下拉狀态:
下拉恢複之後狀态:
發現重新整理結束之後,tableView上面多了一部分空白,使用xcode檢視結構之後發現:
上面多出了一個空白的View,就是MJRefreshHeader 。
-
MJRefreshNormalHeader
MJRefreshNormalHeader:最常用的那種重新整理樣式,有重新整理狀态、有時間、有上下訓示的箭頭。
-(void)MJRefreshNormalHeader_Normal{
__weak DownDefaultController * weakSelf = self;
self.tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
[weakSelf loadData];
[weakSelf.tableView reloadData];
[weakSelf endRefresh];
}];
}
運作效果:
重新整理狀态
結束狀态:
這種樣式應該是最常用的一種了。
-
MJRefreshGifHeader
MJRefreshGifHeader: 左邊帶動圖的重新整理,有時間,有狀态。
-(void)MJRefreshGifHeader_gif{
__weak DownDefaultController * weakSelf = self;
MJRefreshGifHeader * header = [MJRefreshGifHeader headerWithRefreshingBlock:^{
[weakSelf loadData];
[weakSelf.tableView reloadData];
[weakSelf endRefresh];
}];
NSMutableArray * imagesNormal = [NSMutableArray array];
for (int i=1; i<51; i++) {
//dropdown_anim__00060
UIImage * image = [UIImage imageNamed:[NSString stringWithFormat:@"dropdown_anim__000%d",i]];
[imagesNormal addObject:image];
}
NSMutableArray * imagesPulling = [NSMutableArray array];
for (int i=51; i<61; i++) {
//dropdown_anim__00060
UIImage * image = [UIImage imageNamed:[NSString stringWithFormat:@"dropdown_anim__000%d",i]];
[imagesPulling addObject:image];
}
NSMutableArray * imagesRefreshing = [NSMutableArray array];
for (int i=1; i<4; i++) {
//dropdown_loading_01
UIImage * image = [UIImage imageNamed:[NSString stringWithFormat:@"dropdown_loading_0%d",i]];
[imagesRefreshing addObject:image];
}
[header setImages:imagesNormal forState:MJRefreshStateIdle];
[header setImages:imagesPulling forState:MJRefreshStatePulling];
[header setImages:imagesRefreshing forState:MJRefreshStateRefreshing];
self.tableView.mj_header = header;
}
QQ20171122-210207.gif
-
MJRefreshStateHeader
MJRefreshStateHeader: 隐藏上下箭頭圖檔,隻有狀态和時間。
-(void)MJRefreshStateHeader_state{
__weak DownDefaultController * weakSelf = self;
self.tableView.mj_header = [MJRefreshStateHeader headerWithRefreshingBlock:^{
[weakSelf loadData];
[weakSelf.tableView reloadData];
[weakSelf endRefresh];
}];
}
QQ20171122-210533.gif
可以看到,這裡沒有左邊的箭頭,其他功能都是與MJRefreshNormalHeader相同的。
到此為止,我們已經把Header的基本類都使用了一遍,也知道了他們的用法和運作效果。接下來呢,我們再使用上面的幾個類,實作一些其他效果。
-
- 把時間隐藏掉(MJRefreshNormalHeader)
//把時間隐藏掉
-(void)MJRefreshHeader_HideTime{
__weak DownDefaultController * weakSelf = self;
MJRefreshNormalHeader * header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
[weakSelf loadData];
[weakSelf.tableView reloadData];
[weakSelf endRefresh];
}];
//隐藏時間
header.lastUpdatedTimeLabel.hidden = YES;
self.tableView.mj_header = header;
}
我們到MJRefreshNormalHeader的.h中看下,我們都可以取到哪些東西呢?
這裡并沒有時間和狀态資訊,隻有一個旋轉菊花的樣式。不在這裡,就在他的父類中。繼續點選到MJRefreshStateHeader中去看看。
太好了,我們發現,在這個聲明檔案中,我們能夠拿到
重新整理時間和狀态。那麼我們就可以自由的操作它了。雖然是readonly的屬性,但是我們仍然可以更改stateLabel的文字顔色等。
注意:readonly屬性的含義
readonly是修飾的目前的這個屬性,也就是stateLabel這個對象。針對stateLabel,你不可以給它重新指派,也就是不能把另一個Label對象指派給它。但是,stateLabel自己的屬性,比如
等屬性都是可以更改的。可不要搞錯咯。
-
- 自定義文字、顔色等
-(void)MJRefreshHeader_CustomText{
__weak DownDefaultController * weakSelf = self;
MJRefreshNormalHeader * header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
[weakSelf loadData];
[weakSelf.tableView reloadData];
[weakSelf endRefresh];
}];
//設定重新整理狀态的文字
[header setTitle:@"正常狀态" forState:MJRefreshStateIdle];
[header setTitle:@"重新整理狀态" forState:MJRefreshStateRefreshing];
[header setTitle:@"正在下拉狀态" forState:MJRefreshStatePulling];
//設定字型
header.stateLabel.font = [UIFont systemFontOfSize:10];
header.lastUpdatedTimeLabel.font = [UIFont systemFontOfSize:7];
//設定文字顔色
header.stateLabel.textColor = [UIColor redColor];
header.lastUpdatedTimeLabel.textColor = [UIColor blueColor];
self.tableView.mj_header = header;
}
QQ20171122-212505.gif
這裡,我們就是更改了它的文字顔色和大小。
最後,我們介紹下自定義header.
大家直接看源碼吧。
建立一個類CustomHeader繼承自MJRefreshHeader。
.h檔案:
#import "MJRefreshHeader.h"
@interface CustomHeader : MJRefreshHeader
@end
.m檔案:
//
// CustomHeader.m
// TestMJ
//
// Created by weiman on 2017/11/17.
// Copyright © 2017年 weiman. All rights reserved.
//
#import "CustomHeader.h"
@interface CustomHeader()
@property(nonatomic,weak)UILabel * stateLabel;
@property(nonatomic,weak)UIImageView * imageV;
@property(nonatomic,weak)UIActivityIndicatorView *loading;
@end
@implementation CustomHeader
#pragma mark - 重寫方法
#pragma mark 在這裡做一些初始化配置(比如添加子控件)
-(void)prepare{
[super prepare];
//設定控件的高度
self.mj_h = 50;
//添加label
UILabel * label = [[UILabel alloc] init];
label.textColor = [UIColor redColor];
label.font = [UIFont systemFontOfSize:15];
label.textAlignment = NSTextAlignmentCenter;
[self addSubview:label];
self.stateLabel = label;
//圖檔
UIImageView * imageV = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
imageV.image = [UIImage imageNamed:@"refresh"];
imageV.contentMode = UIViewContentModeScaleAspectFit;
[self addSubview:imageV];
self.imageV = imageV;
//loading
UIActivityIndicatorView * loading = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[self addSubview:loading];
self.loading = loading;
}
#pragma mark 在這裡設定子控件的位置和尺寸
-(void)placeSubviews{
[super placeSubviews];
self.stateLabel.frame = self.bounds;
self.imageV.frame = CGRectMake(50, self.mj_h*0.25, 30, 30);
//self.imageV.center = CGPointMake(self.mj_w * 0.5, - self.imageV.mj_h + 20);
self.loading.center = CGPointMake(self.mj_w-30, self.mj_h*0.5);
}
#pragma mark 監聽scrollView的contentOffset改變
-(void)scrollViewContentOffsetDidChange:(NSDictionary *)change{
[super scrollViewContentOffsetDidChange:change];
}
#pragma mark - 監聽scrollView的contentSize改變
-(void)scrollViewContentSizeDidChange:(NSDictionary *)change{
[super scrollViewContentSizeDidChange:change];
}
#pragma mark 監聽scrollView的拖拽狀态改變
-(void)scrollViewPanStateDidChange:(NSDictionary *)change{
[super scrollViewPanStateDidChange:change];
}
#pragma mark - 監聽控件的重新整理狀态
-(void)setState:(MJRefreshState)state{
MJRefreshCheckState;
switch (state) {
case MJRefreshStateIdle:
{
[self.loading stopAnimating];
self.stateLabel.text = @"下拉喲,喲乎乎";
}
break;
case MJRefreshStatePulling:
{
[self.loading stopAnimating];
self.stateLabel.text = @"趕緊放開我吧";
}
break;
case MJRefreshStateRefreshing:
{
self.stateLabel.text = @"資料加載中";
[self.loading startAnimating];
}
break;
default:
break;
}
}
#pragma mark - 監聽拖拽比例(控件被拖出來的比例)
-(void)setPullingPercent:(CGFloat)pullingPercent{
[super setPullingPercent:pullingPercent];
CGFloat red = 1.0 - pullingPercent * 0.5;
CGFloat green = 0.5 - 0.5 * pullingPercent;
CGFloat blue = 0.5 * pullingPercent;
self.stateLabel.textColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0];
}
@end
QQ20171122-213032.gif
到這裡,我們了解了MJRefresh的Header的不同類之間的關系以及他們的使用方法和差别。如果您有時間,建議您自己花點時間自己敲一下,很簡單的,加深記憶,也加深了解。如果您不想自己敲,也可以看我的源碼,demo下載下傳位址:
https://github.com/weiman152/TestMJ.git歡迎大家評論,讨論,指出問題。
最後,祝大家開心。