我正在使用最新的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
,我该在哪里做?
答案 0 :(得分:1)
您不应在变换不是标识的视图上使用setFrame。根据Apple关于UIView框架属性的文档:
如果transform属性不是identity变换,则此属性[frame]的值是未定义的,因此应该被忽略。
在UIView.h中,在frame属性
之上如果转换视图,请不要使用框架,因为它无法正确反映视图的实际位置。使用bounds + center。
因此,如果您在此代码中切换到使用setBounds和setCenter而不是setFrame,那么您可能会获得所需的一致结果。
直接回答问题:如果您还使用setFrame,则没有正确的位置来放置这些变换(比例或旋转)。如果使用setBounds和setCenter,那么无论是在setBounds / setCenter之前还是在setBounds / setCenter之后应用转换,都会得到相同的结果。
编辑:VansFannel指出这是一个CALayer,而不是UIView,因此上述评论并不真正适用。我要离开他们,以免剥夺VansFannel对上下文的评论,也因为它对UIViews来说仍然是个好警告
现在,对于CALayers,如果设置框架(如[_videoPreviewLayer setFrame:self.view.bounds]),即使_videoPreviewLayer具有非标识转换,也会导致_videoPreviewLayer的实际渲染帧为self.view.bounds。重要的是要记住CALayer的框架实际上是派生属性。它来自图层的边界,位置,anchorPoint和变换。当你使用setFrame时,QuartzCore将计算出一个边界和位置,它产生你在现有的anchorPoint和transform下传递给setFrame的帧。
因此,如果您希望这些转换产生任何效果,则应在调用setFrame之后将其设置为。如果先设置变换,那么setFrame将有效地否定它们。如果您绝对需要先设置变换,则必须避免使用setFrame并直接使用图层的边界和位置。