實現一個類似iOS9全局搜索的TableView Section Header效果

jopen 9年前發布 | 16K 次閱讀 iOS9 iOS開發 移動開發

 

最終效果

先上圖:

實現一個類似iOS9全局搜索的TableView Section Header效果

這個TableView的Section Header有什么特殊之處呢?

首先,它是半透明的,其次,當Cell滑動到Header下方的時候Cell的內容并不會因為Header是透明的而顯示在Header的下方。

正常情況下應該是長這樣的:

實現一個類似iOS9全局搜索的TableView Section Header效果

可以看見,的確有點丑,但是實現第一張圖中的效果其實說難不難說簡單也沒那么簡單,關鍵是要利用好一個東西:layer.mask

mask即遮罩,如果對一個UIView的layer設置了mask,所達到的效果就是UIView只顯示遮罩非透明部分所覆蓋的那部分的內容,其他的地方都會被遮擋。利用mask可以做很多很多炫酷的動畫,比如 這個動畫 ,不過一樣,我們也可以使用mask來實現圖1中的效果。

說說思路

實現一個類似iOS9全局搜索的TableView Section Header效果

假設Header的高度是20px,圖中情況需要做特殊處理的Header一定位于UITableView的最頂部,我們所需要做的就是,根據當前UITableView的contentOffSet以及Header的高度,計算出對應的Cell需要隱藏的部分,以此為依據為Cell創建一個大小與其一樣大小的mask,其中需要隱藏的那部分設為透明,剩下的設為純色,這個操作可以在scrollViewDidScroll的回調方法中進行

直接亮代碼

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
UITableView* tableView = (UITableView*)scrollView;
//遍歷TableView中所有顯示的cell
for (UITableViewCell *cell in tableView.visibleCells) {
//計算需要隱藏的高度:當前scrollView的contentOffset的y坐標+Header的高度-cell的y坐標
CGFloat hiddenFrameHeight = scrollView.contentOffset.y + HEADERHEIGHT - cell.frame.origin.y;
if (hiddenFrameHeight >= 0 && hiddenFrameHeight <= cell.frame.size.height) {
//該方法用于對cell設置mask
[cell maskCellFromTop:hiddenFrameHeight];
}
}
}

下面就是cell的操作了,這里因為跟cell的具體內容無關,可以使用category直接寫擴展
- (void)maskCellFromTop:(CGFloat)margin {
if (margin > 0) {
self.layer.mask = [self visibilityMaskWithLocation:margin/self.frame.size.height];
self.layer.masksToBounds = YES;
} else {
self.layer.mask = nil;
}
}

- (CAGradientLayer *)visibilityMaskWithLocation:(CGFloat)location {
CAGradientLayer *mask = [CAGradientLayer layer];
mask.frame = self.bounds;
//上半部分是透明,下半部分非透明
mask.colors = [NSArray arrayWithObjects:(id)[[UIColor colorWithWhite:1 alpha:0] CGColor], (id)[[UIColor colorWithWhite:1 alpha:1] CGColor], nil];
mask.locations = [NSArray arrayWithObjects:[NSNumber numberWithFloat:location], [NSNumber numberWithFloat:location], nil];
return mask;
}

貼效果圖

實現一個類似iOS9全局搜索的TableView Section Header效果

另外還有一些細節

1.分割線不屬于cell,所以要實現這個效果,分割線需要直接在cell里加而不是使用系統自帶的

2.在cell初始化或者復用的時候記得重置mask的狀態

最后我把項目推到了github上,大家可以直接去看下源碼 https://github.com/luckymore0520/LMTableViewHeaderMask

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!