如何防止剪裁 UIImageView 蒙版

How to prevent clipping of UIImageView mask

我想将聊天气泡蒙版应用于图像视图,我希望蒙版图像能够缩放以适合图像视图的框架。这是我用来创建和应用遮罩的代码:

let mask = CALayer()
let maskImage = UIImage(named: "chatGif")!
mask.contents = maskImage.CGImage
mask.frame = CGRectMake(0, 0, imageView.frame.width, imageView.frame.height)
imageView.layer.mask = mask
imageView.layer.masksToBounds = true

这是我的面具:

然而这是我得到的:

当我向蒙版图像添加切片(即创建可调整大小的帽内嵌)时,我得到了这个:

我做了一个最小的项目来演示这个问题并把它 here

我根本不明白为什么我的蒙版图像的右侧和底部被剪掉了。蒙版的框架和边界与图像视图相匹配,用于蒙版的图像实际上比图像视图小,所以我希望它不会覆盖整个东西,而不是被部分剪裁。

有人可以解释一下这里发生了什么吗?我该如何防止这种行为?

编辑:我一直在玩这个,当我设置遮罩的大小以匹配 maskImage 大小时,结果更有意义,如下所示:

let mask = CALayer()
let maskImage = UIImage(named: "chatGif")!
mask.contents = maskImage.CGImage
mask.frame = CGRectMake(0, 0, maskImage.size.width, maskImage.size.height)
imageView.layer.mask = mask
imageView.layer.masksToBounds = true

这给了我:

或者通过对蒙版资产进行切片,我在 的回答中得到了图像。这仍然不是我想要的,因为掩码没有被拉伸以填充 imageView 并且两侧周围的大部分被屏蔽掉了,但我至少可以理解在这种情况下发生了什么。我将蒙版的框架设置为小于 imageView 的框架,因此它当然不会填满整个区域。

不过,我希望将蒙版的框架设置为与 imageView 的框架相匹配,这将使我在最后一张屏幕截图中看到的蒙版的右边缘和下边缘与右边缘和下边缘对齐imageView 的边缘。如果我打印出蒙版的框架、边界和 contentsRect,它们正是我所期望的:框架和边界与 imageView 匹配,而 contentsRect(0.0, 0.0, 1.0, 1.0)。据我了解,CALayer 将根据 contentsRect 显示其部分内容,因此除非该矩形小于 1.0x1.0,否则应显示整个内容图像。正确的?但为什么这不是我所看到的?

我下载了您的演示项目并重写了一些代码,如下所示:

重写 func viewDidLoad() { super.viewDidLoad()

let mask = CALayer()
let maskImage = UIImage(named: "chatGif")!
print("image size is \(maskImage.size)")
mask.contents = maskImage.CGImage
mask.frame = CGRect(origin: CGPointZero, size: maskImage.size)
imageView.layer.mask = mask
imageView.layer.masksToBounds = true

}

你的maskImage的图片大小是(39.5, 32.5)。你的 chatGif.png

好像有问题

快照

好吧,我终于弄明白是怎么回事了。我将相同的调试打印语句添加到我在实际项目中放入的示例项目中,发现 imageViews 在我设置掩码时的帧比我预期的要大得多,而不是它的最终显示尺寸。这是有道理的,因为在示例项目中,在布置任何子视图之前,我在 viewDidLoad 中设置了掩码。

我没有意识到在我的实际项目中打印出值时会出现这种情况,因为我的 UIImageViewUITableViewCell 中,所以它的未初始化大小与占位符相同故事板中的大小,并不比最终大小大多少,所以读起来并没有明显太大。

现在要是我能回到生命的最后 4 小时就好了。

编辑:澄清一下,如果在图像视图设置了最终布局大小后 运行,初始代码工作正常。所以你应该在 viewDidLayoutSubviews 中设置遮罩,或者如果它是 table/collection 单元格你可以检查 layoutSubviews 中的框架大小是否已更改。