這兩天又看了一個新浪微博個人中心界面的一個小功能。
事實上在這大約一年之前,我已經(jīng)做過類似的Demo。那個時候我應(yīng)該還在為自己的畢業(yè)設(shè)計而忙活,當(dāng)時做這個效果的時候我用了一個可能所有的初學(xué)者都會想到的一個方法,那就是給tableView分組。
首先把上邊頭像后邊高度為200px的背景作為一組,然后把下邊的選項卡與微博作為另外一組。這樣的結(jié)果就是,我要去判斷當(dāng)前是第0組還是第一組,以此來返回對應(yīng)的section的header。
但是這次我運用的方法就顯得不那么... 畢竟每個人都要不斷學(xué)習(xí),不斷提高自己。期初這個方法也是我在看啊崢的文章中看到的。但是我一直認為,不管是自己研究出來的,還是從別的地方看來的,能夠消化吸收變成自己的才是真理。
我們先來看一下實現(xiàn)以后的效果:
AGWeiboUserInfo.gif
其實,實現(xiàn)的思想也就以下兩點:
- 1、導(dǎo)航欄,導(dǎo)航欄的透明度其實是隨著scrollView向上的滾動而變的,所以說他們肯定是存在一定的聯(lián)系。
- 2、選項卡,底部所有微博列表上方的選項卡隨著tableView的向上的滾動最終會卡在導(dǎo)航欄下方不動,類似于tableView中section的header。但事實上在這里我們根本不用這樣做,我們只需要讓這個選項卡的頂部始終黏貼在他上方的頭像背景圖的底部,而后設(shè)置頭像背景圖的最小高度不小于64(即導(dǎo)航欄的高度)即可。
一、搭建界面
配圖1
從層次劃分上看出來類似tableView的header以及tab在self.view上的添加順序是在mainTableView之后的,這樣就能在我們調(diào)整tableView的contentInset時候,讓他們蓋在tableView上方。需要注意的是用戶頭像是在header這個view中的這樣才能保證tableView在上下滾動的時候頭像始終都保持在header的中心位置。
二、設(shè)置初始界面
在viewDidLoad中,我們要修改當(dāng)前頁面的初始狀態(tài),包括tableView的偏移位置,頂部導(dǎo)航欄的透明狀態(tài),以及導(dǎo)航欄標題。
#pragma mark - setupUI
- (void)setupUI {
// tableView
_defaultOffsetY = -(kTableViewHeaderDefH + kTableViewTabH);
[self.mainTableView setContentInset:UIEdgeInsetsMake(-_defaultOffsetY, 0, 0, 0)];
self.automaticallyAdjustsScrollViewInsets = NO;
[self.mainTableView setTableFooterView:[[UIView alloc] init]];
// navigationBar
[self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault];
[self.navigationController.navigationBar setShadowImage:[[UIImage alloc] init]];
// title
UILabel *titleLabel = [[UILabel alloc] init];
titleLabel.text = @"Agenric";
[titleLabel sizeToFit];
self.navigationItem.titleView = titleLabel;
_titleLabel = titleLabel;
_titleLabel.alpha = 0;
_titleLabel.hidden = YES;
}
三、監(jiān)聽tableView的滾動
- 我們事先給header的view一個NSLayoutConstraint類型的屬性
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *tableViewHeaderH;```
* 根據(jù)用戶滾動的偏移量來計算tableViewHeaderH.constant的值,我們知道tableView的contentOffset.y初始值是與header和tab的高度和,也就是說他們之間需要滿足這樣的關(guān)系
* 1、定義關(guān)于header的兩個宏
``` objc
#define kTableViewHeaderDefH 200
#define kTableViewHeaderMinH 64```
* 2、header的高度要同時滿足以下兩個條件
``` objc
tableViewHeaderH.constant = kTableViewHeaderDefH - (tableView. contentOffset.y - (header.height + tab.height))
tableViewHeaderH.constant >= kTableViewHeaderMinH ```
* 需要注意的是為什么我們要設(shè)置一個kTableViewHeaderMinH呢,因為在滾動tableView的時候,我們要保證在其向上滾動時,選項卡最后是要停留在導(dǎo)航欄下邊類似tableView的section的header的狀態(tài),但其實,事實上我們只是做了一個假的section的header,它的頂部是粘在頭像背后的那個高度為200px的header底部的,也就是說如果這個header的高度如果變?yōu)?的話選項卡就會被導(dǎo)航欄完全掩蓋掉,這顯然不是我們要的結(jié)果,這也是為什么上一步中我說header要滿足的條件的第二條的原因。
* 最后還要處理的就是導(dǎo)航欄的標題Label,在viewDidLoad中我們把導(dǎo)航欄中的標題Label的透明度設(shè)為了0,以及hidden屬性設(shè)置成了YES。這樣我們在計算當(dāng)前導(dǎo)航欄的透明度時一旦透明度大于0時,就要開始顯示這個Label,并且實時修改其透明度,反之就要繼續(xù)隱藏這個Label。
###### 至此,這個小功能就被我們實現(xiàn)了。
---
> 注:此文章首發(fā)在[簡書](http://www.lxweimin.com)轉(zhuǎn)載請說明出處。
如果你想看到完整的代碼,可以去[這里](https://github.com/agenric/AGWeiboUserInfo)。