Summary: I cannot get CALayer to respond correctly to orientation changes. Whenever I try to use cgaffinetransform, I get strange results (the layer is not centered). Any help would be appreciated! thanks,
Process I am adding a video preview using a subclass of AVCaptureVideoPreviewLayer. When the device is in portrait orientation, everything looks great. The problem occurs when the device rotates in landscape orientation (left or right) or portrait upside down.
I am adding a video preview using a subclass of AVCaptureVideoPreviewLayer. When the device is in portrait orientation, everything looks great. The problem occurs when the device rotates in 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 displays correctly in portrait mode. When I try to rotate the device, the preview layer behaves strangely. It does not seem to resize, and it does not rotate correctly.
I tried to fix this 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 above method, I see progress. Now the layer rotates correctly, reflecting the current orientation of the device, and it displays correctly in landscape mode, but NOT in portrait mode.
The layer is not set correctly, it is not centered on the screen (look at the screenshot). To find out what happened, I added the 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);
And get the following result:
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 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
Pay attention to the second line of debug output. The preview layer frame moves to 128, -128. Can someone explain to me why this is happening and how to fix orientation problems using the preview layer? Thank you Janusz