【问题标题】:How to prevent clipping of UIImageView mask如何防止 UIImageView 蒙版的剪辑
【发布时间】:2016-11-01 21:23:49
【问题描述】:

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

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

这给了我:

或者对蒙版资产进行切片,我在J.Hunter 的答案中得到了图像。这仍然不是我想要的,因为面具没有被拉伸以填充imageView,并且侧面的很大一部分被掩盖了不应该的,但我至少可以理解在这种情况下发生了什么。我将蒙版的框架设置为小于 imageView 的框架的大小,所以它当然不会填满整个区域。

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

【问题讨论】:

  • 或许this thread可以帮到你
  • 不幸的是,我不能使用CGImageCreateWithMask 方法,因为在我的实际项目中,我使用FLAnimatedImageView 来显示gif,所以掩码需要在UIImageView 层,而不是@987654347 @层

标签: ios uiimageview calayer


【解决方案1】:

好的,我终于弄清楚了发生了什么。我将相同的调试打印语句添加到我在实际项目中创建的示例项目中,并发现我设置掩码时的imageViews 帧比我预期的要大得多,而不是最终的显示屏尺寸。这是有道理的,因为在示例项目中,我在 viewDidLoad 中设置了掩码,然后才布置了任何子视图。

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

现在,如果我能找回我生命的最后 4 个小时就好了。

编辑:澄清一下,如果在图像视图设置了最终布局大小之后运行初始代码,则它可以正常工作。所以你应该在viewDidLayoutSubviews中设置掩码,或者如果它是一个表格/集合单元格你可以在layoutSubviews中检查框架大小是否发生了变化。

【讨论】:

  • 我也遇到了同样的问题,你是怎么解决的?
  • 我更新了我的解决方案。您只需要在设置最终大小后运行初始代码。
  • 谢谢,我在 uicollectionViewCell 内的 imageView 上应用蒙版时遇到了同样的问题,我设法通过在 cellForItemAt 函数中调用 cell.setNeedsLayout() cell.layoutIfNeeded() 并在我的自定义单元格
【解决方案2】:

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

覆盖 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 似乎有问题

快照

【讨论】:

  • 这就是我对chatGif 资产进行切片得到的结果,这与调用resizableImageWithCapInsets 相同。当您这样做然后获取 maskImage 的大小时,该大小是资产的最小大小。如果您查看 chatGif.png 文件,您可以看到它是 294x174。我想要的是使蒙版帧大小与 imageView 帧大小相同,并将蒙版缩放到该大小而不是更大。我会用更多信息更新我的问题。
  • @NewShelbyWoo 这让我很困惑。我用 Photoshop 打开 chatGif.png 并检查频道,一切正常。
猜你喜欢
  • 2012-12-11
  • 2017-07-01
  • 2015-05-04
  • 2013-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-07
相关资源
最近更新 更多