iOS CAlayer Orientation AVCaptureVideoPreviewLayer不会旋转 [英] iOS CAlayer Orientation AVCaptureVideoPreviewLayer doesn't rotate
问题描述
摘要:
我无法强迫CALayer正确响应方向更改。
每当我尝试使用cgaffinetransform时,我会得到奇怪的结果(图层不居中)。
任何帮助将不胜感激!
谢谢,
Summary: I can't force the CALayer to respond correctly to orientation changes. Whenever I try to use cgaffinetransform I am getting weird results (layer is not centered). Any help will be appreciated! thanks,
流程
我正在使用AVCaptureVideoPreviewLayer子类添加视频预览。当设备处于纵向时,一切看起来都很好。当设备旋转到横向(左或右)或纵向上下颠倒时,会出现此问题。
Process I am adding a preview of video using AVCaptureVideoPreviewLayer subclass. When device is in a portrait orientation everything looks fine. The problem appears when device is rotated to landscape orientation (left or right) or portrait upside down.
我正在使用AVCaptureVideoPreviewLayer子类添加视频预览。当设备处于纵向时,一切看起来都很好。当设备旋转到横向(左或右)或纵向上下颠倒时,会出现此问题。
I am adding a preview of video using AVCaptureVideoPreviewLayer subclass. When device is in a portrait orientation everything looks fine. The problem appears when device is rotated to landscape orientation (left or right) or portrait upside down.
我使用以下代码添加预览图层:
I am adding a preview layer using the following code:
CGRect layerRect = [[[self view] layer] bounds];
[[[self captureManager] previewLayer] setBounds:layerRect];
[[[self captureManager] previewLayer]setFrame:CGRectMake(0, height, width, height)];
[[[self captureManager] previewLayer] setPosition:CGPointMake(CGRectGetMidX(layerRect),CGRectGetMidY(layerRect))];
并且在纵向模式下正确显示。
当我尝试旋转设备时,预览图层表现得很奇怪。它似乎没有调整自身大小,并且它无法正确旋转。
And it is displayed properly in portrait mode. When I try to rotate the device, preview layer behaves weird. It seems like it doesn't resize itself, and it doesn't rotate correctly.
我尝试通过添加以下方法来修复它
I tried to fix it by adding the following method
-(void)rotateLayer{
CALayer * stuckview = [[self captureManager] previewLayer];
CGRect layerRect = [[[self view] layer] bounds];
UIDeviceOrientation orientation =[[UIDevice currentDevice]orientation];
switch (orientation) {
case UIDeviceOrientationLandscapeLeft:
stuckview.affineTransform = CGAffineTransformMakeRotation(M_PI+ M_PI_2); // 270 degress
NSLog(@"Landscape Left");
[stuckview setPosition: CGPointMake(self.view.bounds.size.width /2.0, self.view.bounds.size.height /2.0)];
break;
case UIDeviceOrientationLandscapeRight:
stuckview.affineTransform = CGAffineTransformMakeRotation(M_PI_2); // 90 degrees
NSLog(@"Landscape Right");
[stuckview setPosition: CGPointMake(self.view.bounds.size.width /2.0, self.view.bounds.size.height /2.0)];
break;
case UIDeviceOrientationPortraitUpsideDown:
stuckview.affineTransform = CGAffineTransformMakeRotation(M_PI); // 180 degrees
NSLog(@"Landscape Upside down");
break;
default:
stuckview.affineTransform = CGAffineTransformMakeRotation(0.0);
break;
}
float h1 = stuckview.frame.size.height;
float w1 = stuckview.frame.size.width;
if(UIDeviceOrientationIsPortrait(orientation))
{
stuckview.position =CGPointMake(h1/2.0, w1/2.0);
NSLog(@"Portrait");
}
else{
stuckview.position =CGPointMake(w1/2.0, h1/2.0);
NSLog(@"Portrait");
}
}
添加上述方法后,我可以看到进度。现在图层旋转正确反映当前设备方向,并且在横向模式下正确显示,但不在纵向模式下显示。
After adding the method above I can see a progress. Now layer rotates correctly reflecting current device orientation and it's displayed correctly in landscape mode, but NOT in portrait mode.
图层位置不正确,不在中心位置屏幕(看截图)。为了看看发生了什么,我添加了以下调试语句:
The layer is not positioned correctly, it isn't centered on the screen (look at the screenshot). To see what's happening I added following debug statements:
CALayer * stuckview = [[self captureManager] previewLayer];
CGRect layerRect = [[[self view] layer] bounds];
float h = stuckview.bounds.size.height;
float w = stuckview.bounds.size.width;
float x = stuckview.bounds.origin.x;
float y = stuckview.bounds.origin.y;
float h1 = stuckview.frame.size.height;
float w1 = stuckview.frame.size.width;
float x1 = stuckview.frame.origin.x;
float y1 = stuckview.frame.origin.y;
NSLog(@"%f %f %f %f ", h,w,x,y );
NSLog(@"%f %f %f %f ", h1,w1,x1,y1 );
NSLog(@"Anchor Point: %f %f",stuckview.anchorPoint.x, stuckview.anchorPoint.y);
NSLog(@"Position: %f %f",stuckview.position.x, stuckview.position.y);
CGAffineTransform at = stuckview.affineTransform;
NSLog(@"Affine Transform After : %f %f %f %f %f %f %f", at.a,at.b, at.c, at.d, at.tx,at.tx, at.ty);
并获得以下输出:
2012-09-30 13:25:12.067 RotatePreviewLayer[2776:907] 1024.000000 768.000000 0.000000 0.000000
2012-09-30 RotatePreviewLayer [2776:907] 1024.000000 768.000000 128.000000 -128.000000
2012-09-30 RotatePreviewLayer[2776:907] 1024.000000 768.000000 128.000000 -128.000000
2012-09-30 13:25:12.070 RotatePreviewLayer[2776:907] Portrait
2012-09-30 13:25:12.072 RotatePreviewLayer[2776:907] Anchor Point: 0.500000 0.500000
2012-09-30 13:25:12.074 RotatePreviewLayer[2776:907] Position: 512.000000 384.000000
2012-09-30 13:25:12.076 RotatePreviewLayer[2776:907] Affine Transform after: -1.000000 0.000000 -0.000000 -1.000000 0.000000 0.000000 0.000000
注意调试输出的第二行。预览图层的帧移动128,-128。
任何人都可以解释为什么会发生这种情况以及如何解决预览图层的方向问题?
谢谢你,
Janusz
Notice the second line of the debug output. The frame of the preview layer is moved by 128,-128. Can anyone explain me why is this happening and how to fix the orientation issues with the preview layer? thank you, Janusz
推荐答案
我仍然不确定是什么导致了这个问题,但我设法修理它。我是这样做的:
I am still not sure what's causing the problem but I managed to fix it. Here is how I did it:
在viewDidLoad中我添加了一个图层:
in viewDidLoad I am adding a layer:
CGRect layerRect = [[[self view] layer] bounds];
[[[self captureManager] previewLayer] setBounds:layerRect];
[[[self captureManager] previewLayer] setPosition:CGPointMake(CGRectGetMidX(layerRect),CGRectGetMidY(layerRect))];
[[[self view] layer] addSublayer:[[self captureManager] previewLayer]];
然后我将对rotateLayer方法的调用添加到didRotate
Then I am adding call to the rotateLayer method to didRotate
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
[self rotateLayer];
}
最后,rotateLayer方法如下:
and finally the rotateLayer method looks like:
-(void)rotateLayer{
CALayer * stuckview = [[self captureManager] previewLayer];
CGRect layerRect = [[[self view] layer] bounds];
UIDeviceOrientation orientation =[[UIDevice currentDevice]orientation];
switch (orientation) {
case UIDeviceOrientationLandscapeLeft:
stuckview.affineTransform = CGAffineTransformMakeRotation(M_PI+ M_PI_2); // 270 degress
break;
case UIDeviceOrientationLandscapeRight:
stuckview.affineTransform = CGAffineTransformMakeRotation(M_PI_2); // 90 degrees
break;
case UIDeviceOrientationPortraitUpsideDown:
stuckview.affineTransform = CGAffineTransformMakeRotation(M_PI); // 180 degrees
break;
default:
stuckview.affineTransform = CGAffineTransformMakeRotation(0.0);
[stuckview setBounds:layerRect];
break;
}
[stuckview setPosition:CGPointMake(CGRectGetMidX(layerRect),CGRectGetMidY(layerRect))];
}
我仍然不明白为什么它以这种方式运作。如果有人能解释它会很棒。
I still don't understand why it works in this way. If anyone can explain it will be great.
这篇关于iOS CAlayer Orientation AVCaptureVideoPreviewLayer不会旋转的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!