概述
支付寶首頁參雜了很多效果在里面,其中刷新的效果著實(shí)吸引了我。它采用了中段刷新嚼摩,上拉聯(lián)動的方案進(jìn)行頁面的展示。分析了一下,這樣做的目的是為了保證用戶在刷新的時候頂部不留刷新空白使得界面美觀柜候,在上拉加載更多的時候頭部隨著界面的上拉隱藏,保證用戶在瀏覽內(nèi)容的時候有更多的空間去展示內(nèi)容。
分析
通過界面效果开泽,大致能夠感覺到界面是由tableView與一個headerView組成峦耘,這里存在爭議的地方是headerView是tableView的一部分還是一個獨(dú)立于tableView而存在的一個部分。
分析一下以上的兩種情況:
- headerView是tableView的一部分
headerView是tableView的一部分,在下拉加載更多的時候,界面效果確實(shí)能夠滿足條件。但是下拉刷新的添加上存在點(diǎn)問題了,細(xì)心的你會發(fā)現(xiàn)支付寶中的刷新是在headerView下面,也就是說如果headerView是tableView的頭部的話,那么刷新不會出現(xiàn)在界面的中間位置,而會在tableView的頭部上方,也就是頂部∪袂兀可見這種方案是不可行的斤葱。
- headerView是獨(dú)立出來的一部分芹血,與tableView在界面上隸屬于同級
簡單說,就是headerView與tableView均在一層View上弟劲,這里又有一點(diǎn)問題熊榛,就是tableView頂部直接放在headerView的下面是否可行呢?理論上tableView放在headerView的下面之后困曙,下拉刷新就變得正常了,頂部headerView的的動態(tài)移動可以通過tableView的滾動的offset進(jìn)行調(diào)整鱼填,貌似也沒什么問題,所以按照上面的方法實(shí)現(xiàn)阻桅,結(jié)果有點(diǎn)小瑕疵:tableView向上滾動的時候頂部的headerView能夠正常滾動蚓土,但是tableView由于向上滾動,會被自身的frame截掉部分內(nèi)容病袄,感覺怪怪的,這也是我之前發(fā)布的帶頭圖的下拉刷新的界面實(shí)現(xiàn)(tabelView的section刷新錯覺問題所在,效果如
上劃聯(lián)動
所示。
支付寶首頁在上拉的時候,tableView的頂部內(nèi)容并沒有被截掉,顯然tableView的內(nèi)容展示部分要包括頭部的header位置胡桃,這樣才能保證上拉的時候內(nèi)容不會被截掉亡容,換句話說也就是tableView的位置應(yīng)該在headerView下面,而且頂部與headerView的頂部保持一致。
這里有個問題坤塞,如果將headerView放在tableView的上面冯勉,那么tabelView的上面內(nèi)容會被headerView遮住,這個很好解決摹芙,只需要設(shè)置tableView的contentInset的內(nèi)容偏移到headerView的高度即可珠闰,如上圖所示。至于上劃聯(lián)動直接使用方案一中的方法就能滿足需求瘫辩。
實(shí)現(xiàn)
經(jīng)過分析之后伏嗜,我們實(shí)際上主要解決兩個主要問題:
- tableView的內(nèi)容偏移設(shè)置
- 上拉的時候動態(tài)改變頭部headerView的位置,完成聯(lián)動效果
tableView的內(nèi)容偏移設(shè)置可以直接在tableView創(chuàng)建的時候進(jìn)行設(shè)置伐厌,如下:
- (UITableView *)tableView{
if (!_tableView) {
MJWeakSelf;
_tableView = [UITableView new];
_tableView.dataSource = self;
_tableView.delegate = self;
//設(shè)置內(nèi)容偏移
_tableView.contentInset = UIEdgeInsetsMake(202, 0, 0, 0);
//設(shè)置滾動條偏移
_tableView.scrollIndicatorInsets = UIEdgeInsetsMake(202, 0, 0, 0);
_tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
weakSelf.rowNum = 10;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[_tableView.mj_header endRefreshing];
});
[weakSelf.tableView reloadData];
}];
_tableView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{
weakSelf.rowNum += 10;
[weakSelf.tableView reloadData];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[weakSelf.tableView.mj_footer endRefreshing];
});
}];
}
return _tableView;
}
如何在上拉加載的時候動態(tài)更新headerView的位置已達(dá)到聯(lián)動效果呢承绸?可以借助scrollViewDidScroll
進(jìn)行界面的更新,如下所示:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
//頁面沒有加載的時候不進(jìn)行調(diào)整
if (!self.view.window) {
return;
}
CGFloat offsetY = scrollView.contentOffset.y;
//上拉加載更多(頭部還沒有隱藏)挣轨,動態(tài)移動header
if (offsetY > -202 & offsetY < 0) {
[self.topImg mas_updateConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(-offsetY - 202);
}];
}else if(offsetY > 0){ //頭部隱藏军熏,固定頭部位置
[self.topImg mas_updateConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(-202);
}];
}else{ //下拉刷新
[self.topImg mas_updateConstraints:^(MASConstraintMaker *make) {
make.top.mas_equalTo(0);
}];
}
}
好了,設(shè)置完之后我們來看看實(shí)現(xiàn)的效果卷扮,如下:
總結(jié)
其實(shí)類似與這樣的效果的地方還有很多荡澎,例如上拉的過程中,菜單懸浮晤锹,下拉局部刷新摩幔,都可以使用這樣的方式去處理,只需要更改滾動時候的headerView的偏移既可鞭铆,是不是覺得很有用呢或衡?需要的同學(xué)可以下載Demo。