之前項(xiàng)目中很多地方用到了滑動(dòng)視圖帅掘,三個(gè)界面五個(gè)界面或界面?zhèn)€數(shù)不定的情況都有,這里以簡(jiǎn)書 APP 的個(gè)人主頁(yè)為例脓鹃,總結(jié)一下逸尖,一則對(duì)自己也有好處,二則希望對(duì)看到的朋友有所幫助瘸右。
-
簡(jiǎn)書APP個(gè)人主頁(yè):
demo 效果圖:
簡(jiǎn)單說(shuō)下思路及核心代碼:
思路:
- 導(dǎo)航欄上面的頭像會(huì)隨著視圖的上下滑動(dòng)而變大變小娇跟,這里注冊(cè)了一個(gè)通知,用來(lái)監(jiān)聽(tīng)視圖的上下滑動(dòng)太颤,可以根據(jù)偏移量的值來(lái)改變頭像的大小苞俘。
- 此 UI 頁(yè)面分為三部分,第一部分是信息展示龄章,用來(lái)顯示昵稱簽名等吃谣;第二部分是標(biāo)簽欄,即“動(dòng)態(tài)”做裙,“文章”岗憋,“更多”這三個(gè)標(biāo)簽;第三部分是主要顯示內(nèi)容锚贱;
- 我這里用了這樣的思路:頁(yè)面底部是一個(gè) UIScrollView; 接著 UIScrollView 上面 add 了三個(gè) UITableView 仔戈;信息展示以及標(biāo)簽欄放在 UITableView 的 tableHeaderView 中;接著挨個(gè)實(shí)現(xiàn)其功能即可拧廊。
核心代碼:
- 頭像跟隨頁(yè)面上下滑動(dòng)而變大變小
- 這里是頭像變大變小時(shí)調(diào)用的代碼监徘,如果你的項(xiàng)目中用到了此功能,可以直接把這個(gè)類拿過(guò)去吧碾,然后調(diào)用下面這幾句代碼就可以實(shí)現(xiàn)了凰盔。另外點(diǎn)擊頭像的回調(diào)也通過(guò) block 傳了出來(lái),你可以在此處做些操作倦春,比如更改頭像等等户敬。
self.headerImageView = [[NNPersonalHomePageHeaderImageView alloc] initWithImage:[UIImage imageNamed:@"header"]];
[self.headerImageView reloadSizeWithScrollView:self.dynamicTableView];
self.navigationItem.titleView = self.headerImageView;
[self.headerImageView handleClickActionWithBlock:^{
NSLog(@"你點(diǎn)擊了頭像按鈕");
}];
- tableView 的頭部視圖
- 這里另外建了兩個(gè) UIView 類落剪,一個(gè)用來(lái)顯示基本信息(昵稱簽名等),一個(gè)用來(lái)顯示標(biāo)簽欄(動(dòng)態(tài)尿庐,文章等標(biāo)簽)著榴,額外建這兩個(gè) UIView 類是為了減少控制器中的代碼。
- (void)setupHeaderView {
UIView *headerView = [[NNPersonalHomePageHeaderView alloc] init];
headerView.frame = CGRectMake(0, 0, NNScreenWidth, NNHeadViewHeight + NNTitleHeight);
[self.view addSubview:headerView];
self.headerView = headerView;
NNPersonalHomePageTitleView *titleView = [[NNPersonalHomePageTitleView alloc] init];
[headerView addSubview:titleView];
self.titleView = titleView;
titleView.backgroundColor = [UIColor whiteColor];
[titleView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.mas_equalTo(headerView);
make.bottom.equalTo(headerView.mas_bottom);
make.height.mas_equalTo(NNTitleHeight);
}];
[self.scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.bottom.equalTo(self.view);
make.top.mas_equalTo(headerView.top);
}];
__weak typeof(self) weakSelf = self;
titleView.titles = @[@"動(dòng)態(tài)", @"文章", @"更多"];
titleView.selectedIndex = 0;
titleView.buttonSelected = ^(NSInteger index){
[weakSelf.scrollView setContentOffset:CGPointMake(NNScreenWidth * index, 0) animated:YES];
};
}
- 主要內(nèi)容
- 主要內(nèi)容就是頁(yè)面下部展示的具體內(nèi)容屁倔,這里用了三個(gè) UITableView ,依次添加到 UIScrollView 中暮胧,這里代碼有些臃腫锐借,后期再做優(yōu)化,有興趣的童鞋也可以幫忙改一下哈往衷。
/// 主要內(nèi)容
- (void)setupContentView {
NNContentScrollView *scrollView = [[NNContentScrollView alloc] init];
scrollView.delaysContentTouches = NO;
[self.view addSubview:scrollView];
self.scrollView = scrollView;
scrollView.pagingEnabled = YES;
scrollView.showsVerticalScrollIndicator = NO;
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.delegate = self;
scrollView.contentSize = CGSizeMake(NNScreenWidth * 3, 0);
UIView *headView = [[UIView alloc] init];
headView.frame = CGRectMake(0, 0, 0, NNHeadViewHeight + NNTitleHeight);
self.tableViewHeadView = headView;
NNContentTableView *dynamicTableView = [[NNContentTableView alloc] init];
dynamicTableView.delegate = self;
dynamicTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.dynamicTableView = dynamicTableView;
dynamicTableView.tableHeaderView = headView;
[scrollView addSubview:dynamicTableView];
[dynamicTableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(scrollView);
make.width.mas_equalTo(NNScreenWidth);
make.top.equalTo(self.view);
make.bottom.equalTo(self.view);
}];
NNContentTableView *articleTableView = [[NNContentTableView alloc] init];
articleTableView.delegate = self;
articleTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.articleTableView = articleTableView;
articleTableView.tableHeaderView = headView;
[scrollView addSubview:articleTableView];
[articleTableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(scrollView).offset(NNScreenWidth);
make.width.equalTo(dynamicTableView);
make.top.bottom.equalTo(dynamicTableView);
}];
NNContentTableView *moreTableView = [[NNContentTableView alloc] init];
moreTableView.delegate = self;
moreTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.moreTableView = moreTableView;
moreTableView.tableHeaderView = headView;
[scrollView addSubview:moreTableView];
[moreTableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(scrollView).offset(NNScreenWidth * 2);
make.width.equalTo(dynamicTableView);
make.top.bottom.equalTo(dynamicTableView);
}];
}
- 左右或上下滑動(dòng)頁(yè)面
- 這里為 UIScrollView 添加了代理钞翔,一旦滑動(dòng)視圖,便會(huì)調(diào)用下面這兩個(gè)方法席舍。為了區(qū)分是左右滑動(dòng)還是上下滑動(dòng)布轿,這里做了簡(jiǎn)單的判斷,
if (scrollView == self.scrollView)
来颤,那么這就是左右滑動(dòng)汰扭,因?yàn)?UITableView 是上下滑動(dòng)的,所有左右滑動(dòng)就是 UIScrollView 的滑動(dòng)福铅,需要切換 UITableView 的顯示內(nèi)容萝毛,在這里做相應(yīng)的操作即可;如果if (scrollView == self.scrollView || !scrollView.window)
這個(gè)條件不成立滑黔,那么就是 UITableView 的滑動(dòng)笆包,就是上下滑動(dòng),在這里需要改變“標(biāo)簽欄”的frame略荡,因?yàn)椤皹?biāo)簽欄”需要顯示在導(dǎo)航欄下邊位置庵佣。
- 這里為 UIScrollView 添加了代理钞翔,一旦滑動(dòng)視圖,便會(huì)調(diào)用下面這兩個(gè)方法席舍。為了區(qū)分是左右滑動(dòng)還是上下滑動(dòng)布轿,這里做了簡(jiǎn)單的判斷,
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
if (scrollView == self.scrollView) {
CGFloat contentOffsetX = scrollView.contentOffset.x;
NSInteger pageNum = contentOffsetX / NNScreenWidth + 0.5;
self.titleView.selectedIndex = pageNum;
}
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView == self.scrollView || !scrollView.window) {
return;
}
CGFloat offsetY = scrollView.contentOffset.y;
CGFloat originY = 0;
CGFloat otherOffsetY = 0;
if (offsetY <= NNHeadViewHeight) {
originY = -offsetY;
if (offsetY < 0) {
otherOffsetY = 0;
} else {
otherOffsetY = offsetY;
}
} else {
originY = -NNHeadViewHeight;
otherOffsetY = NNHeadViewHeight;
}
self.headerView.frame = CGRectMake(0, originY, NNScreenWidth, NNHeadViewHeight + NNTitleHeight);
for ( int i = 0; i < self.titleView.titles.count; i++ ) {
if (i != self.titleView.selectedIndex) {
UITableView *contentView = self.scrollView.subviews[i];
CGPoint offset = CGPointMake(0, otherOffsetY);
if ([contentView isKindOfClass:[UITableView class]]) {
if (contentView.contentOffset.y < NNHeadViewHeight || offset.y < NNHeadViewHeight) {
[contentView setContentOffset:offset animated:NO];
self.scrollView.offset = offset;
}
}
}
}
}
上面只是簡(jiǎn)單的介紹下,具體的代碼還請(qǐng)到 demo 中 查看汛兜,如有疑問(wèn)或有建議的地方巴粪,歡迎討論。