Swift - CAGradientLayer使用详解3(边界渐隐效果)
作者:hangge | 2017-09-04 08:10
平时我们使用一些直播类 App 时会发现,屏幕上的消息是不断自下而上向上的滚动显示。同时最上面的消息滚出消息区域边界时,不会直接消失不见,而是有一种渐隐消失的效果。
类似的还有一些音乐播放器,屏幕上的歌词会随着时间向上滚动,而最上方的歌词随着滚动也会逐渐消失隐藏。下面演示如何实现这种边界渐隐的效果。
1,效果图
我们向上滑动消息列表时会发现,上方的消息到了边界处会渐隐消失。
2,实现原理
同上文一样,这个同样是通过 CAGradientLayer(渐变层)配合 mask(遮罩)来实现:
- 不同的是 CAGradientLayer 这次不再是使用颜色渐变,而是透明度渐变(最上方位置透明度从 0 渐变到 1)
- 不要直接对 tableView 设置遮罩,否则透明部分会随着 tableView 一起滚动。正确做法是先将 tableView 放到一个 View 中,然后对这个容器 View 设置遮罩,这样渐隐遮罩会一直停留在这个容器 View 的顶部位置。
3,样例代码
(1)列表单元格(MyTableViewCell.swift)
import UIKit class MyTableViewCell: UITableViewCell { //用于显示消息的文本标签 var label:UILabel! override init(style: UITableViewCellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) setSubviews() } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) setSubviews() } //初始化页面子元素 private func setSubviews() { //单元格背景透明 backgroundColor = .clear //单元格无法选中 selectionStyle = .none //创建文本标签,并设置相关样式 label = UILabel() label.frame = CGRect(x: 10, y: 3, width: 300, height: 20) label.font = UIFont.systemFont(ofSize: 11) label.textColor = .white label.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.7) label.layer.cornerRadius = 9 label.layer.masksToBounds = true contentView.addSubview(label) } }
(2)主视图控制器(ViewController.swift)
import UIKit class ViewController: UIViewController, UITableViewDataSource { //单元格identifier(方便复用) let cellIdentifier = "MessageCell" override func viewDidLoad() { super.viewDidLoad() //创建放置tableView的容器 let tableViewCotainer = UIView() tableViewCotainer.frame = CGRect(x: 0, y: 300, width: view.frame.size.width, height: view.frame.size.height - 320) view.addSubview(tableViewCotainer) //创建tableView let tableView = UITableView() tableView.frame = tableViewCotainer.bounds tableView.rowHeight = 26 tableView.backgroundColor = .clear tableView.separatorStyle = .none tableView.showsVerticalScrollIndicator = false tableView.register(MyTableViewCell.self, forCellReuseIdentifier: cellIdentifier) tableView.dataSource = self tableViewCotainer.addSubview(tableView) //创建渐变层 let gradientLayer = CAGradientLayer() gradientLayer.colors = [UIColor.black.withAlphaComponent(0.0).cgColor, UIColor.black.cgColor] gradientLayer.frame = tableViewCotainer.bounds; gradientLayer.locations = [0, 0.15, 1] //设置tableView父容器tableViewCotainer的遮罩 tableViewCotainer.layer.mask = gradientLayer } //获取单元格 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) as! MyTableViewCell //设置单元格内容(通过富文本设置) let attributeString = NSMutableAttributedString(string: " 游客\(Int(arc4random()%100)+100):这是一条弹幕消息") //设置字体颜色 attributeString.addAttribute(NSForegroundColorAttributeName, value: UIColor.orange, range: NSMakeRange(0, 8)) cell.label.attributedText = attributeString return cell } //获取单元格高度 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 25 } }
源码下载:hangge_1778.zip
全部评论(5)
研究了下, 要做到歌词上下边界模糊 , 只需要设置locations即可[0, 0.5, 1]
站长回复:解决了就好 :)
请教一下, QQ, 网易云音乐类似的下方也有个遮罩, 这个怎么实现, 单纯添加梯度颜色数组colors效果不好
站长回复:你指的是网易云音乐歌词的遮罩吗?我看了下,直接用本文的透明渐变遮罩就可以实现了。
航哥,为什么有的gradientLayer要加到view.layer里面 ,有的不需要?
这一篇没加,上一篇加进去了
站长回复:作为mask的图层可以不加到view.layer里面(当然你加了也没关系)。比如本文gradientLayer是作为tableViewCotainer的mask,所以它可以不加到view.layer里面。同理,上一篇文章里的progressLayer也可以不加。
真心感谢分享 默默支持
站长回复:不客气,也谢谢你的支持。
航哥请教下,上一篇文章里,是将gradientLayer的遮罩设置成progressbar,这里为什么是奖container的遮罩设置成gradientLayer
站长回复: