iOS自定義簡(jiǎn)易刷新視圖(仿MJRefresh)

前言:之前在實(shí)現(xiàn)下拉刷新,上拉加載功能時(shí)浩村,我一直都是使用MJRefresh進(jìn)行集成做葵。一直想自己寫一個(gè)類似于MJRefresh的刷新控件,方便與自己對(duì)MJRefresh原理的理解心墅,昨天抽出了時(shí)間自己寫了一個(gè)類似的刷新控件酿矢,在這做一下記錄與分享。


Github: 看這里




思路整理與代碼實(shí)現(xiàn):

1. 通過(guò)上/下拉頁(yè)面顯示刷新提示文字我們可以判斷出怎燥,刷新提示文字的顯示與否是根據(jù)當(dāng)前scrollView的偏移值來(lái)確定的瘫筐。在這里我們的一切動(dòng)態(tài)顯示和用戶交互跟當(dāng)前scrollView的偏移值存在著聯(lián)系。所以我們給MyRefreshView提供一個(gè)類方法的接口铐姚,將scrollView傳進(jìn)去:

+ (MyRefreshView *)refreshViewWithScrollView:(UIScrollView *)scrollView{

MyRefreshView *refreshView = [[MyRefreshView alloc]init];

refreshView.frame = CGRectMake(20, -25, KScreenWidth-20, 18);

refreshView.scrollView = scrollView;

[refreshView setupView];

return refreshView;

}

2. 添加控件严肪,這里我們需要一個(gè)提示文本,一個(gè)顯示偏移進(jìn)度的圓形進(jìn)度條谦屑,一個(gè)刷新時(shí)的loading等待圈:

@interface MyRefreshView ()

/**

刷新狀態(tài)值

*/

@property (nonatomic, assign) NSInteger refreshFlag;

/**

刷新菊花圈

*/

@property (nonatomic, strong) UIActivityIndicatorView *activityIndicatorView;

/**

偏移動(dòng)畫

*/

@property (nonatomic, strong) CAShapeLayer *scheduleLayer;

/**

監(jiān)聽視圖

*/

@property (nonatomic, strong) UIScrollView *scrollView;

/**

刷新文字

*/

@property (nonatomic, strong) UILabel *titleLabel;

@end

3. 在setupView方法中構(gòu)建視圖驳糯,將refreshView添加到當(dāng)前的scrollView上。并用KVO將refreshView添加為scrollView的觀察者氢橙,實(shí)時(shí)監(jiān)聽scrollView的偏移值

刷新提示文字:在refreshView上加上一個(gè)Label酝枢;

圓形進(jìn)度條:這里我們用CAShapeLayer實(shí)現(xiàn)。CAShapeLayer有strokeStart和strokeEnd屬性悍手,在繪圖時(shí)帘睦,這兩個(gè)屬性可以改變path的起始位置和結(jié)束位置。設(shè)置strokeStart和strokeEnd初始值都為0坦康,然后根據(jù)scrollView的偏移值來(lái)改變strokeEnd的值竣付,從而達(dá)到改變進(jìn)度的目的;

loading視圖:這里用系統(tǒng)自由的菊花圈UIActivityIndicatorView滞欠,實(shí)際操作中也可以設(shè)置gif動(dòng)畫或者CAAnimation來(lái)實(shí)現(xiàn)古胆;

refreshFlag:刷新狀態(tài)值(根據(jù)偏移值判斷當(dāng)前是否處于可刷新狀態(tài));

- (void)setupView{

self.titleLabel = [[UILabel alloc]initWithFrame:CGRectMake(25, 0, KScreenWidth-20-25, 18)];

[self.titleLabel setAdjustsFontSizeToFitWidth:YES];

[self addSubview:self.titleLabel];

self.scheduleLayer = [[CAShapeLayer alloc]init];

self.scheduleLayer.frame = CGRectMake(0, 0, 18, 18);

self.scheduleLayer.strokeStart = 0;

self.scheduleLayer.fillColor = [UIColor clearColor].CGColor;

self.scheduleLayer.strokeColor = [UIColor whiteColor].CGColor;

self.scheduleLayer.backgroundColor = [UIColor clearColor].CGColor;

self.scheduleLayer.lineWidth = 2.0;

self.scheduleLayer.strokeEnd = 0.0;

[self.scheduleLayer setTransform:CATransform3DMakeRotation(-M_PI_2, 0, 0, 1)];

self.scheduleLayer.path = [UIBezierPath bezierPathWithOvalInRect:CGRectInset(CGRectMake(0, 0, 18, 18), 2, 2)].CGPath;

[self.layer addSublayer:self.scheduleLayer];

self.activityIndicatorView = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(0, 0, 18, 18)];

[self addSubview:self.activityIndicatorView];

[self.scrollView addSubview:self];

[self.scrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];

}

4. 動(dòng)態(tài)監(jiān)聽

在observeValueForKeyPath方法中獲取到當(dāng)前的偏移值筛璧,并進(jìn)行相關(guān)的邏輯判斷

這里我們?cè)O(shè)置的刷新臨界點(diǎn)為-80逸绎;而strokeStar和strokeEnd的取值范圍為0-1之間。當(dāng)scrollView被拖拽時(shí)夭谤,顯示refreshView棺牧,根據(jù)偏移值動(dòng)態(tài)改變相關(guān)屬性的值。

結(jié)束拖拽時(shí)朗儒,根據(jù)當(dāng)前的偏移值判斷refreshView是否進(jìn)入刷新狀態(tài)颊乘。

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void *)context{

if (self.refreshing) {

return;

}

if ([keyPath isEqualToString:@"contentOffset"]) {

CGFloat height = [change[@"new"] CGPointValue].y;

if (height > 0) {

height = 0;

}else if (height > -80){

height = height/-80.0;

}else{

height = 1.0;

}

if (self.scrollView.isDragging) {

self.hidden = NO;

if (height == 1.0) {

self.title = @"釋放刷新";

}else{

self.title = @"下拉刷新";

}

[self.activityIndicatorView stopAnimating];

self.scheduleLayer.strokeEnd = height;

self.scheduleLayer.hidden = NO;

self.refreshFlag = height;

}else{

if (self.refreshFlag == 1.0){

self.refreshing = YES;

[self.scrollView setContentOffset:CGPointMake(0, -80) animated:YES];

[self.activityIndicatorView startAnimating];

self.title = @"正在刷新";

self.scheduleLayer.hidden = YES;

self.scheduleLayer.strokeEnd = 0;

}else{

[self.activityIndicatorView stopAnimating];

self.scheduleLayer.hidden = NO;

self.scheduleLayer.strokeEnd = height;

}

}

}

}

在title的set方法中改變當(dāng)前的刷新文字

- (void)setTitle:(NSString *)title{
    _title = title;
    self.titleLabel.text = title;
}

5. 數(shù)據(jù)請(qǐng)求成功后参淹,設(shè)置結(jié)束刷新接口,結(jié)束刷新動(dòng)畫,并改變刷新狀態(tài)乏悄,將scrollView的偏移值設(shè)置為最初狀態(tài)

- (void)endRefresh{
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)1.0*NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        self.refreshing = NO;
        self.refreshFlag = 0;
        self.scheduleLayer.strokeEnd = 0;
        [self.activityIndicatorView stopAnimating];
        [self.scrollView setContentOffset:CGPointMake(0, 0) animated:YES];
        self.hidden = YES;
    });
    
   
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末承二,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子纲爸,更是在濱河造成了極大的恐慌亥鸠,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件识啦,死亡現(xiàn)場(chǎng)離奇詭異负蚊,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)颓哮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門家妆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人冕茅,你說(shuō)我怎么就攤上這事伤极。” “怎么了姨伤?”我有些...
    開封第一講書人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵哨坪,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我乍楚,道長(zhǎng)当编,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任徒溪,我火速辦了婚禮忿偷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘臊泌。我一直安慰自己鲤桥,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開白布渠概。 她就那樣靜靜地躺著茶凳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪高氮。 梳的紋絲不亂的頭發(fā)上慧妄,一...
    開封第一講書人閱讀 49,821評(píng)論 1 290
  • 那天顷牌,我揣著相機(jī)與錄音剪芍,去河邊找鬼。 笑死窟蓝,一個(gè)胖子當(dāng)著我的面吹牛罪裹,可吹牛的內(nèi)容都是我干的饱普。 我是一名探鬼主播,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼状共,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼套耕!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起峡继,我...
    開封第一講書人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤冯袍,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后碾牌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體康愤,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年舶吗,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了征冷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡誓琼,死狀恐怖检激,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情腹侣,我是刑警寧澤叔收,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站傲隶,受9級(jí)特大地震影響今穿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜伦籍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一蓝晒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧帖鸦,春花似錦芝薇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至攻锰,卻和暖如春晾嘶,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背娶吞。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工垒迂, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人妒蛇。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓机断,卻偏偏與公主長(zhǎng)得像楷拳,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子吏奸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)欢揖、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,065評(píng)論 4 62
  • 從標(biāo)題就可以看出奋蔚,我今天要寫的是那個(gè)大名鼎鼎的史玉柱她混,曾經(jīng)是那么一個(gè)大學(xué)生,建立起自己的軟件王國(guó)泊碑,又有保健品后花園...
    風(fēng)狼志閱讀 193評(píng)論 0 0
  • 面朝大海春暖花開产上,在這個(gè)美麗的時(shí)光遇到最美的你。讓這個(gè)充滿著愛的冬季因?yàn)橛心愣识旯罚愠霈F(xiàn)在這個(gè)美麗的熒幕上晋涣,不...
    鐘情于小丸子閱讀 320評(píng)論 6 2
  • 小程序1月9號(hào)正式發(fā)布谢鹊,在發(fā)布之前,跟很多人交流過(guò)×羝荆現(xiàn)在大家疑問(wèn)基本上是佃扼,小程序沒(méi)有入口,用戶每次打開都需要的重新...
    三磊閱讀 847評(píng)論 1 1
  • 寫在前面 好幾天前蔼夜,我看完了劇版《致青春》兼耀,沒(méi)有急著去找原著和幾年前的電影,亦不想吐槽劇中的那些漏洞求冷,只想靜下心來(lái)...
    驛路奇奇閱讀 896評(píng)論 8 13