Swift - CAGradientLayer使用详解3(边界渐隐效果)
平时我们使用一些直播类 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
}
}

研究了下, 要做到歌词上下边界模糊 , 只需要设置locations即可[0, 0.5, 1]
请教一下, QQ, 网易云音乐类似的下方也有个遮罩, 这个怎么实现, 单纯添加梯度颜色数组colors效果不好
航哥,为什么有的gradientLayer要加到view.layer里面 ,有的不需要?
这一篇没加,上一篇加进去了
真心感谢分享 默默支持
航哥请教下,上一篇文章里,是将gradientLayer的遮罩设置成progressbar,这里为什么是奖container的遮罩设置成gradientLayer