今日頭條的加載頁面有這么一個動畫

我覺得效果不錯,可以借鑒到APP中。不過網(wǎng)上沒有現(xiàn)成的demo,就自己實現(xiàn)了一個。
首先來看一下動畫效果。
今日頭條四個字靜止,斜方向的灰色陰影從左至右劃過。注意:陰影部分只在今日頭條這四個字中才會出現(xiàn),四字之外的陰影部分是隱藏的。
因此,這顯然不是灰色陰影的frame變化。
那么,要達到如上的動畫效果,就要使用本文的主角CAGradientLayer了。
你可能知道這個CALayer的子類是可以處理漸變色,那么這里就不對它的概念做介紹了,我們直接在代碼中來解釋。
ok,直接上代碼。
1.
首先我們創(chuàng)建一個UIView的子類FlashView,并在init方法中添加上今日頭條這張圖片。
class FlashView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(imageView)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
lazy var imageView: UIImageView = {
let imgV = UIImageView()
imgV.image = UIImage(named: "icon") //icon是今日頭條四字的圖片,需要自己找,也可以換成其他圖片
imgV.frame = bounds
return imgV
}()
}
2.
接著給這個類添加一個CAGradientLayer屬性
let gradientLayer: CAGradientLayer = {
let layer = CAGradientLayer()
let colors = [
UIColor.lightGray.cgColor,
UIColor.gray.cgColor,
UIColor.gray.cgColor,
UIColor.lightGray.cgColor
]
layer.colors = colors
let locations: [NSNumber] = [
-0.4,
-0.39,
-0.24,
-0.23
]
layer.locations = locations
layer.startPoint = CGPoint(x: 0.0, y: 0.6)
layer.endPoint = CGPoint(x: 1.0, y: 0.4)
return layer
}()
(1)這里colors中,兩邊的lightGray對應今日頭條的底色,中間的gray對應陰影的顏色
(2)這里locations代表顏色漸變的起始位置,它的數(shù)量需要與colos對應。
第一個值-0.4代表colors中第一個顏色的起始位置,是-(layer的寬度 * 0.4)。使用-0.4是因為,陰影需要從今日頭條左邊出來,動畫看起來會自然~
第二個值-0.39與-0.4相差0.01,代表第二個顏色與第一個顏色相交處有layer的寬度 * 0.01的寬度間隙,實際上就是陰影部分邊的寬度
那么-0.39與-0.24之間就代表陰影部分的寬度了
(3)startPoint和endPoint代表layer漸變的方向,它們的取值范圍是0~1。x軸由0到1好理解,y軸因為要設置陰影的一個偏轉角度,因此分別為0.6和0.4。當你交換兩個值的時候,會發(fā)現(xiàn)陰影的偏轉方向也會相反,這樣有助于理解
3.
接下來我們要將imageView設為layer的mask(即蒙版)。我們要達到陰影只在有文字的部分顯示,就要將這個文字的圖片設為陰影部分的蒙版。我們就拿到了文字的部分,并通過layer的colors為它們的顏色重新賦值。
這個概念需要多思考一下。我們在layoutSubviews里來設置。
override func layoutSubviews() {
gradientLayer.frame = self.bounds
gradientLayer.mask = imageView.layer
imageView.frame = gradientLayer.bounds
}
4.
剩下最后一步,當然是設置動畫,讓陰影部分動起來啦~我們?yōu)閘ayer的locations屬性添加動畫。
override func didMoveToWindow() {
super.didMoveToWindow()
layer.addSublayer(gradientLayer)
let gradientAnimation = CABasicAnimation(keyPath: "locations")
gradientAnimation.fromValue = [-0.8,-0.79,-0.64,-0.63]
gradientAnimation.toValue = [1.5,1.51,1.76,1.77]
gradientAnimation.duration = 2.0
gradientAnimation.repeatCount = MAXFLOAT
gradientLayer.add(gradientAnimation, forKey: nil)
}
5.
以上就是對這個動畫FlashView的封裝,接下來我們實例化它,并添加到界面上就可以了。
class ViewController: UIViewController {
lazy var flashView: FlashView = {
let flashView = FlashView(frame: CGRect(x: 100, y: 100, width: 264, height: 72))
return flashView
}()
//注意frame的寬高應該按今日頭條四字的原圖大小比例來設置。
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(flashView)
}
}