CALayer内容超出边界 - iOS

9
我正在尝试使用CGAffinetransform实现相机缩放。变换是正确的,但当我将其缩放到更大的尺寸时,它超出了我分配给AVCaptureVideoPreviewLayer的框架。我尝试将masksToBounds属性设置为YES,但没有帮助。
我能够将其限制在其框架内吗?
编辑: 我想要的是,我可以指定相机预览层的特定区域,如果我对其应用缩放变换(即,预览层的框架扩展),则指定区域外的部分将被剪切。
3个回答

38

你应该将要缩放的图层放在另一个图层中并对其进行遮罩(即父图层)。同样的方法也适用于视图。

例如:你有两个视图/图层:clippingViewscalingView,其中 scalingView 是 clippingView 的子视图,而 clippingView 是实际上剪裁到其边界的视图。

[clippingView addSubview:scalingView];
clippingView.clipsToBounds = YES;

或者使用图层

[clippingLayer addSublayer:scalingLayer];
clippingLayer.masksToBounds = YES;

我尝试添加一个单独的视图(UIImageView,因为某些原因,但我想这不应该有影响),并将一个子层添加为预览层,我将其设置为self.view.layer的子层。我将masksToBounds设置为YES,但仍然超出边界。 - neeraj
我所做的是,我创建了一个视图,并设置了它的框架,使得预览层位于其中。然后我将其属性clipsToBounds设置为YES。这就是全部操作。文档中说,如果将此属性设置为Yes,则视图的所有内容都将位于指定的框架内。实际上,在此之前我从未遇到过这个属性。 - neeraj

4
你们的说法都有一定道理,但我想澄清一下。
举个例子,如果我们通过 [self.view.layer addSublayer:previewLayer] 向视图中添加了类似 AVCaptureVideoPreviewLayer 的内容。
1. 只有在要求主层遮罩到边界时,[self clipsToBounds] 才能发挥作用。因此需要使用 [self.view.layer masksToBounds];
2. 仅仅因为你的视图和它的层都有 frame,并不意味着它具有 bounds。如果它没有 bounds,那么就没有什么可以遮罩。所以应该这样做: self.view.layer.bounds = self.view.frame;
3. 所以这里总结一下,记住我是在自己的 UIView 类中做的,所以不需要调用 self.view。
previewLayer.bounds = self.frame;
self.layer.bounds = self.frame;

self.layer.masksToBounds = YES;
previewLayer.masksToBounds = YES;

[self setBounds:self.frame];
[self clipsToBounds];

这正是我一直在寻找的。即使我有一个自定义的UIView,我也想使用AVFoundation显示相机。谢谢! - Kunal Shrivastava

0
我正在添加图层的视图的 clipsToBounds 属性应该已经设置为 YES

更改已接受的答案有什么特别的原因吗?你基本上说的和我一样。 - David Rönnqvist
  1. 在此之前,您的回答可能没有被接受,可能是因为我当时还没有理解。我对层和视图感到困惑。
  2. 昨天我查看了我的回答,发现没有被接受的答案,所以我接受了自己的回答...
- neeraj
但是现在我看到你的被接受了。所以,犯了一个错误。 - neeraj
那么你需要改变的就只有这些吗?我也遇到了完全相同的问题。图层比框架本身还要大。我设置了一个 NSLog 来验证视图框架本身并没有变大。尽管我已经将 clipsToBounds 设置为 yes,并且在预览图层上将 maskstobounds 也设置为 yes,但预览图层仍然超出了边界。 - Nathan Kellert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接