我正在实施类似于Apple相机应用的照片/视频选择界面。我需要进行手动界面旋转,因为我不希望预览视图旋转,但我确实想要相应地旋转控件。因此,我的视图控制器(应用程序的根视图控制器)中有以下代码:
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
要检测方向更改,我在viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(deviceOrientationDidChange)
name:UIDeviceOrientationDidChangeNotification
object:[UIDevice currentDevice]];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
当我以除了人像之外的方向启动应用程序时,这可以按预期的除外。我的回调被调用;但是,当前设备方向始终为UIDeviceOrientationPortrait
,即使我在启动应用程序时将设备侧向握住也是如此。状态栏方向也是如此。
如何在应用启动后立即找出设备方向?我知道这是可能的,因为Apple正在使用他们的相机应用程序。问题是,是否有任何官方方式,或者他们是否使用了一些神奇的内部API?
安娜的答案证明是正确的,但你也应该阅读评论。 TL; DR :当应用未针对它们进行优化时,效果会发生在iPhone 6(Plus)上。
答案 0 :(得分:1)
首先,您不希望查看UIDevice方向(请参阅this post)。
我认为在UI完成配置之前,你会得到一个虚假的结果。换句话说,它报告肖像,因为它在启动过程中的那个时候还没准备好。为什么要发送通知?不确定;但是,你绝对不想将它们用于你的任务。
我不太明白你使用的初始方向是什么,但我有另一种方法可以解决你的问题:你可以通过反转来保持视图静态。当视图控制器收到旋转消息(即viewDidRotate,iOS 8之前版本)时,您可以更改静态视图上的变换,使其沿与旋转方向相反的方向旋转。
也许有一些聪明的方法可以用autolayout来做,但我还没想出来...... :-p
编辑:
一些代码......
YMMV - 这个有效,但我有一段时间没碰过它!您可能需要稍微玩一下......与我在评论中所说的相反,看起来我是动画旋转。但是,它真的不动!我认为反旋转动画会被整个显示器的系统旋转取消。或者其他东西。
simViewControllerContainer是我阻止旋转的视图。
- (void)viewDidLoad
{
[super viewDidLoad];
// Set simView container's orientation if the device started in landscape
if ( self.interfaceOrientation == UIInterfaceOrientationLandscapeRight ) {
simViewControllerContainer.center = (CGPoint) {self.view.bounds.size.height/2, self.view.bounds.size.width/2};
simViewControllerContainer.transform = CGAffineTransformMakeRotation(-M_PI/2);
}
else if ( self.interfaceOrientation == UIInterfaceOrientationLandscapeLeft ) {
simViewControllerContainer.center = (CGPoint) {self.view.bounds.size.height/2, self.view.bounds.size.width/2};
simViewControllerContainer.transform = CGAffineTransformMakeRotation(M_PI/2);
}
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
BOOL doubleRotation =
(UIInterfaceOrientationIsPortrait(self.interfaceOrientation) && UIInterfaceOrientationIsPortrait(toInterfaceOrientation)) ||
(UIInterfaceOrientationIsLandscape(self.interfaceOrientation) && UIInterfaceOrientationIsLandscape(toInterfaceOrientation));
if ( toInterfaceOrientation == UIInterfaceOrientationLandscapeRight ) {
[UIView animateWithDuration:duration animations:^{
if ( !doubleRotation ) {
// For a double-rotation, we don't want to change the center -- it's the same:
// a double-rotation is landscape to landscape or portrait to portrait -- same center.
simViewControllerContainer.center = (CGPoint) {self.view.bounds.size.height/2, self.view.bounds.size.width/2};
}
simViewControllerContainer.transform = CGAffineTransformMakeRotation(-M_PI/2);
}];
}
else if ( toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft ) {
[UIView animateWithDuration:duration animations:^{
if ( !doubleRotation ) {
simViewControllerContainer.center = (CGPoint) {self.view.bounds.size.height/2, self.view.bounds.size.width/2};
}
simViewControllerContainer.transform = CGAffineTransformMakeRotation(M_PI/2);
}];
}
else if ( toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown ) {
[UIView animateWithDuration:duration animations:^{
if ( !doubleRotation ) {
simViewControllerContainer.center = (CGPoint) {self.view.bounds.size.height/2, self.view.bounds.size.width/2};
}
simViewControllerContainer.transform = CGAffineTransformIdentity;
}];
}
else if ( [UIDevice currentDevice].orientation == UIDeviceOrientationPortrait ) {
[UIView animateWithDuration:duration animations:^{
if ( !doubleRotation ) {
simViewControllerContainer.center = (CGPoint) {self.view.bounds.size.height/2, self.view.bounds.size.width/2};
}
simViewControllerContainer.transform = CGAffineTransformIdentity;
}];
}
}