效果如下
shot.gif
實現步驟:
1.首先用UIBezierPath創建一個鏤空圓,然后添加鏤空圓到UIImageView上。
2.創建鏤空圓放大動畫。
創建UIImageView的拓展類,在其中創建一個屬性用于存儲之后要用到的CAShapeLayer對象
fileprivate(set) var maskLayer:CAShapeLayer? {
get{
return objc_getAssociatedObject(self, &key) as? CAShapeLayer
}
set(newValue){
objc_setAssociatedObject(self, &key, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
創建方法,用于外部調用添加動畫
public func addCircleOddAnim(){
self.clipsToBounds = true
self.addMaskView()//添加遮罩
self.addamin()//添加動畫
}
addMaskView方法用于添加遮罩層,初始全灰色半透明。
private func addMaskView(){
//UIImageView中心點
let centerX = self.bounds.size.width/2
let centerY = self.bounds.size.height/2
//圓的半徑
let r = sqrt((centerX)*(centerY)+(centerY)*(centerY))
//在圖片中心創建一個寬高為0的圓
let innerRect :CGRect = CGRect(x: centerX, y:centerY, width: 0, height: 0)
//外層圓,整個圓比UIImageView大一圈,可見下圖
let outerRect :CGRect = CGRect(x: centerX-r, y: centerY-r, width: 2*r, height: 2*r)
if self.maskLayer == nil {
self.maskLayer = CAShapeLayer()
}
let innerPath = UIBezierPath(ovalIn: innerRect)
let outerPath = UIBezierPath(ovalIn: outerRect)
//兩條path合并到一起
outerPath.append(innerPath)
outerPath.usesEvenOddFillRule = true
self.maskLayer!.path=outerPath.cgPath
//填充規則為補集方式
self.maskLayer!.fillRule = kCAFillRuleEvenOdd
self.maskLayer!.fillColor = UIColor(colorLiteralRed: 0.2, green: 0.2, blue: 0.2, alpha: 0.7).cgColor
self.layer.addSublayer(self.maskLayer!)
}
yuandian.png
private func addamin(){
//創建動畫對象
let circleScaleAnim:CABasicAnimation = CABasicAnimation(keyPath: "path")
//起始點shapeLayer的已經創建好的path、即是圖片全灰遮罩
let fromBezier = UIBezierPath(cgPath: self.maskLayer!.path!)
circleScaleAnim.fromValue=fromBezier.cgPath
//UIImageView中心點
let centerX = self.bounds.size.width/2
let centerY = self.bounds.size.height/2
//圓的半徑
let r = sqrt((centerX)*(centerY)+(centerY)*(centerY))
//外層圓
let maskPath:UIBezierPath = UIBezierPath(ovalIn: CGRect(x: centerX-r, y: centerY-r, width: 2*r, height: 2*r))
//內層圓與外層圓交匯
let innerPath:UIBezierPath = UIBezierPath(ovalIn: CGRect(x: centerX-r, y: centerY-r, width: 2*r, height: 2*r))
//取內層圓和外層圓的補集(根本不存在,兩個圓交匯在一起)
maskPath.usesEvenOddFillRule = true
maskPath.append(innerPath)
circleScaleAnim.toValue = maskPath.cgPath
circleScaleAnim.duration = 1
//動畫執行后保持動畫執行后的效果
circleScaleAnim.fillMode = kCAFillModeForwards
circleScaleAnim.isRemovedOnCompletion = false
self.maskLayer!.add(circleScaleAnim, forKey: "path")
}
到這里簡單的鏤空圓動畫就完成了