转载

实现一个类似iOS9全局搜索的TableView Section Header效果

最终效果

先上图:

实现一个类似iOS9全局搜索的TableView Section Header效果

这个TableView的Section Header有什么特殊之处呢?

首先,它是半透明的,其次,当Cell滑动到Header下方的时候Cell的内容并不会因为Header是透明的而显示在Header的下方。

正常情况下应该是长这样的:

实现一个类似iOS9全局搜索的TableView Section Header效果

可以看见,的确有点丑,但是实现第一张图中的效果其实说难不难说简单也没那么简单,关键是要利用好一个东西: layer.mask

mask 即遮罩,如果对一个 UIViewlayer 设置了 mask ,所达到的效果就是 UIView 只显示遮罩非透明部分所覆盖的那部分的内容,其他的地方都会被遮挡。利用 mask 可以做很多很多炫酷的动画,比如 这个动画 ,不过一样,我们也可以使用 mask 来实现 图1 中的效果。

说说思路

实现一个类似iOS9全局搜索的TableView Section Header效果

假设 Header 的高度是 20px ,图中情况需要做特殊处理的 Header 一定位于 UITableView 的最顶部,我们所需要做的就是,根据当前 UITableViewcontentOffSet 以及 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

正文到此结束
Loading...