ios - 如何从 CALayer 中的图像中减去形状?
问题描述
我正在构建一个包含图像和徽章的自定义视图。图片显示了我想要的结果。
我可以使用 Sketch 轻松实现这一点,但编程要困难得多。
我在 CALayer 和 UIBezierPath 中找不到减法运算,所以我不知道如何创建一个剪裁的形状来掩盖图像。
我想要的是
我现在拥有的
class PetAvatarView: UIView {
var image: UIImage? {
didSet {
layer.contents = image?.cgImage
}
}
private let maskLayer = CAShapeLayer()
override init(frame: CGRect) {
super.init(frame: frame)
layer.mask = maskLayer
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
maskLayer.frame = layer.bounds
// image
let imageMaskRadius = bounds.width / 2
let imageMaskCenter = CGPoint(x: imageMaskRadius, y: imageMaskRadius)
let imageMaskPath = UIBezierPath()
imageMaskPath.addArc(withCenter: imageMaskCenter, radius: imageMaskRadius, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: true)
let badgeMaskRadius = bounds.width / 5
let badgeMaskCenter = CGPoint(x: bounds.maxX - badgeMaskRadius, y: bounds.maxY - badgeMaskRadius)
let badgeMaskPath = UIBezierPath()
badgeMaskPath.addArc(withCenter: badgeMaskCenter, radius: badgeMaskRadius, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: true)
let path = imageMaskPath
path.append(badgeMaskPath.reversing())
path.usesEvenOddFillRule = true
maskLayer.path = path.cgPath
}
解决方案
所以我不知道如何创建一个剪裁的形状来掩盖图像
是的你是!你只是自己说的。您可以使用剪辑创建一个形状并使用它来遮盖图像。您的代码的问题在于您实际上没有进行任何剪辑。
这是一个没有徽章的示例,展示了如何从图像上的圆形蒙版中取出圆形“咬”:
那是怎么做的?好吧,我从一个显示小猫图像的图像视图开始。然后我给那个图像视图一个蒙版。面具看起来像这样(如果你能看到面具):
所以现在唯一的问题是如何绘制那个面具。显然,我们通过填充大圆圈来做到这一点。但在我们这样做之前,我们创建一个由小圆圈(右下角)加上整个蒙版的边界框组成的剪切路径。因此,大圆圈最终被夹在该区域中。
请注意,徽章绘制本身,红色圆圈,现在不能是图像视图的子视图或子层,因为我们只是屏蔽了该区域!但是,这不是一个困难的问题。故事中只需要另一种观点。
推荐阅读
- python - 如何查看上次使用 python 更新私有 docker hub 存储库中的 docker 映像的时间
- r - R中两种密度混合的卷积
- sql - ballerina.io SQL LIKE 语句
- apache-kafka - .properties 文件中的变量?
- bash - 计算在线会议的总时间
- r - 使用日期序列,将一个数字除以一个季度的天数
- reactjs - ReactJS Formik,为什么表格没有清除?
- sql - 我可以修改 BigQuery 中多个嵌套 RECORD 中的列,然后保持该列与以前相同的名称和位置吗?
- python - 为什么安装 TensorFlow 需要 google-auth?
- git - 有没有办法查看被 git 隐藏的文件的历史记录?