Custom Camera Rotation problems

2019-02-26 21:47发布

I have a custom camera overlay that, like all camera views, is default in landscape mode. I have some orientation change logic that detect when the orientation changes so I can rotate the buttons and views that I have placed. Also, I have edited the shouldAutoRotateInterfaceTo method so it does not rotate while the camera is on:

- (BOOL)shouldAutorotateToInterfaceOrientation
               (UIInterfaceOrientation)interfaceOrientation  {
        if (cameraIsOn) {
            return NO;
        }
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

Problem: the camera view still rotates into Portrait mode when I tilt the camera into Landscape. This results in the device being in Landscape position while the view is in Portrait, running off of the screen.

If it helps, here is the method I use to detect orientation changes and transform my buttons:

- (void)cameraOrientationChanged  {
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
CGAffineTransform transform;
switch (orientation) {
    case UIDeviceOrientationPortrait:
        transform = CGAffineTransformIdentity;
        self.rotatePrompt.hidden = NO;
        break;
    case UIDeviceOrientationPortraitUpsideDown:
        //transform = CGAffineTransformMakeRotation(180*M_PI/180);
        transform = CGAffineTransformIdentity;
        self.rotatePrompt.hidden = NO;
        break;
    case UIDeviceOrientationLandscapeLeft:
        //transform = CGAffineTransformMakeRotation(90*M_PI/180);
        self.rotatePrompt.hidden = YES;
        transform = CGAffineTransformIdentity;
        break;
    case UIDeviceOrientationLandscapeRight:
        //transform = CGAffineTransformMakeRotation(-90.0*M_PI/180);
        transform = CGAffineTransformMakeRotation(180*M_PI/180);
        self.rotatePrompt.hidden = YES;
        break;
    default:
        transform = CGAffineTransformIdentity;
        break;
}
self.shootButton.transform = transform;
self.cameraTypeButton.transform = transform;
self.photoLibraryButton.transform = transform;
self.changeCameraDirectionButton.transform = transform;
self.flashButton.transform = transform;
self.videoTimerLabel.transform = transform;
self.closeCameraButton.transform = transform;

}

Note This seemed to be working ok before I upgraded to iOS 5.

More Info By looking at my Xib file, I can see that I created the overlay in Portrait mode. When the camera overlay rotates it is moving into Portrait mode while the device is being help in Landscape position.

Even more peculiar, whenever this happens (it does not always happen), I noticed that shouldAutorotateToInderfaceOrientation is not being called in the view controller. I bet that has something to do with the problem here.

2条回答
beautiful°
2楼-- · 2019-02-26 22:06

The problem is with my navigation controller setup. UIImagePickerController sends the rotation message to the root view controller's shouldAutoRotateToInterface: method. However, since I copied the class from an older project (iOS 3), it did not have the shouldAutoRotateToInterface: method automatically copied. Now that I wrote the method in my root view controller, to rotation problem is fixed.

查看更多
老娘就宠你
3楼-- · 2019-02-26 22:24

You seem to be using UIDeviceOrientation when you really should be using UIInterfaceOrientation. UIDeviceOrientation has many more states than UIInterfaceOrientation, so this could result in a device state being something other than what you were expecting for an interface state, for instance UIDeviceOrientationFaceUp can be returned even when the interface orientation (to the user) looks like it should be UIInterfaceOrienataionLandscape. So in your case, your default switch case may be returning more often than you would expect for it to.

If it were me, I would change your - (void)cameraOrientationChanged method to - (void)cameraOrientationChangedTo:(UIInterfaceOrientation)orientation and call that method in shouldAutorotateToInterfaceOrientation:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation  {

    [self cameraOrientationChangeTo:interfaceOrientation];

    if (cameraIsOn) {
        return NO;
    }

    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

UIDeviceOrientation vs UIInterfaceOrientation:

typedef enum {
   UIDeviceOrientationUnknown,
   UIDeviceOrientationPortrait,
   UIDeviceOrientationPortraitUpsideDown,
   UIDeviceOrientationLandscapeLeft,
   UIDeviceOrientationLandscapeRight,
   UIDeviceOrientationFaceUp,
   UIDeviceOrientationFaceDown
} UIDeviceOrientation;

typedef enum {
   UIInterfaceOrientationPortrait           = UIDeviceOrientationPortrait,
   UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
   UIInterfaceOrientationLandscapeLeft      = UIDeviceOrientationLandscapeRight,
   UIInterfaceOrientationLandscapeRight     = UIDeviceOrientationLandscapeLeft
} UIInterfaceOrientation;
查看更多
登录 后发表回答