不确定这是否是一个“好”的解决方案。但我会一直坚持下去,直到有人告诉我如何更优雅地解决它!
boxLayer
在“剪切”区域中绘制。然后,我只需设置动画
opacity
boxLayer
func addIndicatorTo(global frame: CGRect) {
let maskLayer = CAShapeLayer()
let boxLayer = CAShapeLayer()
let targetRect = convert(frame, from: nil).insetBy(dx: -4, dy: -4)
let animation = CABasicAnimation(keyPath: "opacity")
let toPath = CGMutablePath()
let boxPath = UIBezierPath(roundedRect: targetRect,
byRoundingCorners: .allCorners,
cornerRadii: CGSize(width: 4, height: 4)).cgPath
toPath.addRect(bounds)
toPath.addPath(boxPath)
toPath.closeSubpath()
boxLayer.fillColor = UIColor.black.withAlphaComponent(0.5).cgColor
boxLayer.path = boxPath
animation.fromValue = 1.0
animation.toValue = 0.0
animation.duration = 0.5
maskLayer.fillRule = .evenOdd
maskLayer.path = toPath
backgroundView.layer.mask = maskLayer
layer.addSublayer(boxLayer)
boxLayer.add(animation, forKey: nil)
CATransaction.begin()
CATransaction.setDisableActions(true)
boxLayer.opacity = 0.0
CATransaction.commit()
}