0

我正在使用最新的 SDK 开发一个 iOS 应用程序。

我这样创建AVCaptureVideoPreviewLayer

// Create the preview layer
_videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
[_videoPreviewLayer setFrame:self.view.bounds];
_videoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.view.layer insertSublayer:_videoPreviewLayer atIndex:0];

现在我想这样做:

_videoPreviewLayer.affineTransform = CGAffineTransformMakeScale(2, 2);

但是,如果我把它放在[_videoPreviewLayer setFrame:self.view.bounds];我得到不同的结果之前,而不是我把它放在后面。

我必须在哪里应用规模?

而且,如果我想设置CGAffineTransformMakeRotation(-M_PI_2); // -90 degrees,我必须在哪里做?

4

1 回答 1

1

您不应该在其变换不是身份的视图上使用 setFrame。根据 Apple 关于 UIView 的 frame 属性的文档:

如果变换属性不是恒等变换,则此属性 [frame] 的值未定义,因此应被忽略。

在 UIView.h 中,在 frame 属性之上

如果视图被转换,请不要使用框架,因为它不会正确反映视图的实际位置。改用边界+中心。

因此,如果您在此代码中切换到使用 setBounds 和 setCenter 而不是 setFrame,您可能会得到您正在寻找的一致结果。

直接回答这个问题:如果您还使用 setFrame,则没有放置这些变换(缩放或旋转)的正确位置。如果您使用 setBounds 和 setCenter,那么无论您在 setBounds/setCenter 之前还是在 setBounds/setCenter 之后应用变换,都将获得相同的结果。

编辑:VansFannel 指出这是一个 CALayer,而不是 UIView,所以上述评论并不真正适用。我离开他们是为了不剥夺 VansFannel 对上下文的评论,也因为它仍然是对 UIViews 的一个很好的警告

现在,对于 CALayers,如果您设置的帧(如 [_videoPreviewLayer setFrame:self.view.bounds])将导致 _videoPreviewLayer 的实际渲染帧为 self.view.bounds,即使 _videoPreviewLayer 具有非身份变换。重要的是要记住 CALayer 的框架实际上是一个派生属性。它派生自层的边界、位置、锚点和变换。当您使用 setFrame 时,QuartzCore 会计算出一个边界和位置,该边界和位置会产生您在现有锚点和变换下传递给 setFrame 的帧。

因此,如果您希望这些转换产生任何效果,您应该在调用 setFrame之后将它们放置。如果您先设置变换,那么 setFrame 将有效地否定它们。如果您绝对需要首先设置变换,那么您必须避免使用 setFrame 并直接使用图层的边界和位置。

于 2013-03-18T18:55:27.573 回答