最近項目用到了支付寶首頁的頭部動畫的效果,這裏就把我的實現原理給大家梳理一下,希望能和大家一起學習進步,先上圖:
首先我們瞭解一下他們的層級關係,還是先看圖,方便解釋:
圖片已經標明的很明白,我們在控制器先放上一個UIScrollView,在它的上面分別放上一個HeaderView(UIView)和一個UITableView。這時需要控制UITableView不能滑動,並且在設置高度時保持和行高*行數一致,也就是說這個方法適用於一些UITableView不必顯示過多的頁面,這裏面不參與UITableView的複用,所有的Cell在一開始就顯示出來了。ok,文字永遠是枯燥的😂,上代碼先:
在父視圖UIScrollView裏面的初始化方法裏
-(instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.delegate = self;
[self headerView];
// 設定tableView的行數(這個tableView是一個自定義的UITableView類)
self.tableView.rowNumber = 20;
// 設定自身的偏移量,tableViewCell的高度是50
self.contentSize = CGSizeMake(0, kHeaderHeight + self.tableView.rowNumber * 50.f + 64.f);
__weak __typeof(self)weakSelf = self;
// 下拉刷新
self.tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
[weakSelf loadMoreData];
}];
}
return self;
}
而在UITableView的類中:
-(void)setRowNumber:(NSInteger)rowNumber {
_rowNumber = rowNumber;
// 重置高度爲:行數(rowNumber) * 行高(kRowHeight)
self.lyf_height = rowNumber * kRowHeight;
[self reloadData];
}
這樣在初始化的時候,其實UITableView中所有的Cell就自動展示了,不存在複用的問題,所以如果需要在UITableView中顯示大量數據的同學這個方法並不可取,至於哪種方法可取呢😏?過幾天我會在更新一篇文章來講解一下。okok,繼續。
咳咳,不用過幾天了,代碼已經更新,文末會爲大家獻上鍊接。
其實如果兩個視圖都是相對靜止的話就很easy了,只是需要控制UIScrollView的滑動方法來實現HeaderView和UINavigationView的隱藏和顯示就可以啦。
#pragma mark - UIScrollViewDelegate
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
CGFloat contentOffsetY = scrollView.contentOffset.y;
if (contentOffsetY < -kHeaderHeight / 2) {
// 當結束滑動的偏移量小於-kHeaderHeight / 2,就開始刷新tableView
[self.tableView.mj_header beginRefreshing];
} else if (contentOffsetY > 0 && contentOffsetY < kHeaderHeight / 2) {
// 當偏移量大於0並且小於kHeaderHeight / 2,就把偏移量設置在CGPointMake(0, 0)
[self setContentOffset:CGPointMake(0, 0) animated:YES];
} else if (contentOffsetY > kHeaderHeight / 2 && contentOffsetY < kHeaderHeight) {
// 當偏移量大於kHeaderHeight / 2並且小於kHeaderHeight,就把偏移量設置在CGPointMake(0, kHeaderHeight)
[self setContentOffset:CGPointMake(0, kHeaderHeight) animated:YES];
}
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
// 偏移量
CGFloat contentOffsetY = scrollView.contentOffset.y;
// 將偏移量放入block
if (self.contentOffsetAction) {
self.contentOffsetAction(contentOffsetY);
}
if (contentOffsetY <= 0) {
// 當偏移量小於0時,頭部視圖的Y值跟隨偏移量上移
self.headerView.lyf_y = contentOffsetY;
// tableView的Y值也是保持不變
self.tableView.lyf_y = contentOffsetY + kHeaderHeight;
// 當tableView沒有刷新時,tableView的contentOffset發生改變
if (![self.tableView.mj_header isRefreshing]) {
self.tableView.contentOffset = CGPointMake(0, contentOffsetY);
}
} else {
// 頭部視圖滾動差的效果
self.headerView.lyf_y = contentOffsetY/2;
}
self.headerView.contentOffsetY = contentOffsetY;
}
至於顯示的動畫方法,大家可以直接下載我的源碼去看看,其實原理還是很簡單的,喜歡的同學可以點一個贊呦😘
github:https://github.com/Fdevelopmenter/LYFTestAli
那麼問題來了,可以UITableView複用的的代碼在哪裏?
https://www.jianshu.com/p/b44a9c633a86
喜歡的同學,兩種方法都可以學習一下哈