在我的实现中,我将 UIView 子类化为我想要旋转的视图,以及类似 viewController 的视图,这只是 NSObject 的子类。
在这个 viewController 中,我做了所有与方向变化相关的检查,决定是否应该改变目标视图的方向,如果是,那么我调用视图的方法来改变它的方向。
首先,我们需要将整个应用程序界面的方向固定为纵向模式,以便我们的 ACCaptureVideoPreviewLayer 始终保持静止。这是在MainViewController.h
:
(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation`
{
return interfaceOrientation==UIInterfaceOrientationPortrait;
}
它对除纵向以外的所有方向都返回 NO。
为了让我们的自定义 viewController 能够跟踪设备方向的变化,我们需要让它成为相应通知的观察者:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(orientationChanged) name:UIDeviceOrientationDidChangeNotification object:nil];
我将这些行放在(void)awakeFromNib
我的 viewController 的方法中。所以每次改变设备方向时,orientationChanged
都会调用viewController的方法。
它的目的是检查设备的新方向是什么,设备的最后一个方向是什么,并决定是否改变它。这是实现:
if(UIInterfaceOrientationPortraitUpsideDown==[UIDevice currentDevice].orientation ||
lastOrientation==(UIInterfaceOrientation)[UIDevice currentDevice].orientation)
return;
[[UIApplication sharedApplication]setStatusBarOrientation:[UIDevice currentDevice].orientation animated:NO];
lastOrientation=[UIApplication sharedApplication].statusBarOrientation;
[resultView orientationChanged];
如果方向与之前或 PortraitUpsideDown 中的方向相同,则什么也不做。否则它将状态栏方向设置为正确的方向,以便当有来电或骨化时,它会出现在屏幕的右侧。然后我还在目标视图中调用方法,其中完成了新方向的所有相应更改,例如旋转、调整大小、移动此视图中与新方向相对应的界面的其他元素。
这是orientationChanged
目标视图的实现:
Float32 angle=0.f;
UIInterfaceOrientation orientation=[UIApplication sharedApplication].statusBarOrientation;
switch (orientation) {
case UIInterfaceOrientationLandscapeLeft:
angle=-90.f*M_PI/180.f;
break;
case UIInterfaceOrientationLandscapeRight:
angle=90.f*M_PI/180.f;
break;
default: angle=0.f;
break;
}
if(angle==0 && CGAffineTransformIsIdentity(self.transform)) return;
CGAffineTransform transform=CGAffineTransformMakeRotation(angle);
[UIView beginAnimations:@"rotateView" context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDuration:0.35f];
self.transform=transform;
[UIView commitAnimations];
当然,您可以在此处添加任何其他更改,例如平移、缩放需要响应新方向并为其设置动画的界面不同视图。
此外,您可能不需要 viewController,但只需在您的视图类中完成所有操作。希望大体思路清晰。
另外,当您不需要方向更改时,不要忘记停止接收通知,例如:
[[NSNotificationCenter defaultCenter]removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
[[UIDevice currentDevice]endGeneratingDeviceOrientationNotifications];