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

来源:互联网 时间:1970-01-01

最终效果

先上图:

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

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

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

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

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

说说思路

假设 Header 的高度是 20px ,图中情况需要做特殊处理的 Header 一定位于 UITableView 的最顶部,我们所需要做的就是,根据当前 UITableView 的 contentOffSet 以及 Header 的高度,计算出对应的 Cell 需要隐藏的部分,以此为依据为 Cell 创建一个大小与其一样大小的 mask ,其中需要隐藏的那部分设为透明,剩下的设为纯色,这个操作可以在 scrollViewDidScroll 的回调方法中进行

直接亮代码 - (void)scrollViewDidScroll:(UIScrollView *)scrollView {UITableView* tableView = (UITableView*)scrollView;//遍历TableView中所有显示的cellfor (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;} 贴效果图

另外还有一些细节

1.分割线不属于cell,所以要实现这个效果,分割线需要直接在cell里加而不是使用系统自带的

2.在cell初始化或者复用的时候记得重置mask的状态

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


相关阅读:
Top