Problem: A有一个应用程序,它对应用程序的不同部分使用横向模式(已锁定)和纵向模式(已锁定) . 现在我有一个可行的解决方案,但它没有自己的问题 .
最理想的是,我希望强制改变方向 . 甚至考虑在需要时进行视图转换 .
Basic flow of App:
-
HomeView(人像)(有几个子推视图,也是纵向并锁定到该视图) .
-
LandscapeView(风景)(其中有5个推出的子视图也是风景)
注意:
-
HomeView有一个到LandscapeView的链接
-
LandscapeView可以返回HomeView
-
在LandscapeView子视图的末尾,它返回到HomeView
基本图像显示了不同视图方向的外观 . (线条表示app的流程,图像的方向表示每个屏幕应该如何)
目前使用以下实现调用/设置如果视图处于纵向模式或横向模式[setLockedToPortait:YES](用于纵向视图)等 .
这个术语可以查询在旋转设备时从iOS使用的界面方向 .
现在,对于转到LandscapeView的情况,我在普通视图的顶部显示一个临时视图,要求使用它将手机旋转到横向 . (从横向视图返回HomeView时也会显示临时视图)
因此,一旦用户旋转了他们的设备,它将触发正确的方向,然后临时视图将隐藏 .
如果用户此时将手机旋转回肖像,它仍将被锁定为横向,因此不会触发另一个视图旋转(也不会出现临时视图或任何内容)
Current Implementation Code::
// ---------------------- NavigationController (subclass of UINavigationController)
@interface NavigationController () {
BOOL isOrientationPortrait;
}
@end
@implementation NavigationController {
UIDeviceOrientation lastAccepted;
UIDeviceOrientation lastKnown;
}
-(void)setLockedToPortait:(BOOL)isLocked {
isOrientationPortrait = isLocked;
}
-(UIDeviceOrientation) getCurrentOrientation {
UIDeviceOrientation orientate = [[UIDevice currentDevice] orientation];
if(orientate == 0) { // needed for simulator
orientate = (UIDeviceOrientation)[UIApplication sharedApplication].statusBarOrientation;
}
return orientate;
}
// Deprecated in iOS6, still needed for iOS5 support.
- (BOOL)shouldAutorotateToInterfaceOrientation:
(UIInterfaceOrientation)toInterfaceOrientation
{
UIDeviceOrientation orientation = [self getCurrentOrientation];
[self setLastKnownOrientation:orientation];
if(isOrientationPortrait == YES) {
if([self isLastKnownPortrait] == YES) {
[self setLastAcceptedOrientation:orientation];
return YES;
} else {
return NO;
}
} else {
if([self isLastKnownLandscape] == YES) {
[self setLastAcceptedOrientation:orientation];
return YES;
} else {
return NO;
}
}
}
// iOS6/7 support
- (BOOL)shouldAutorotate
{
// find out the current device orientation
UIDeviceOrientation orientation = [self getCurrentOrientation];
[self setLastKnownOrientation:orientation];
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
if(isOrientationPortrait == YES) {
if([self isLastKnownPortrait] == YES)
{
UIDeviceOrientation orientation = [self getCurrentOrientation];
[self setLastAcceptedOrientation:orientation];
}
return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
} else {
if([self isLastKnownLandscape] == YES)
{
UIDeviceOrientation orientation = [self getCurrentOrientation];
[self setLastAcceptedOrientation:orientation];
}
return (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight );
}
}
-(void)setLastAcceptedOrientation:(UIDeviceOrientation)orient {
lastAccepted = orient;
}
-(void)setLastKnownOrientation:(UIDeviceOrientation)orient {
lastKnown = orient;
}
-(BOOL)isLastKnownPortrait {
return UIDeviceOrientationIsPortrait(lastKnown);
}
-(BOOL)isLastKnownLandscape {
return UIDeviceOrientationIsLandscape(lastKnown);
}
-(BOOL)isLastAcceptedPortrait {
return UIDeviceOrientationIsPortrait(lastAccepted);
}
-(BOOL)isLastAcceptedLandscape {
return UIDeviceOrientationIsLandscape(lastAccepted);
}
Current Problems:
-
加载视图后,对于用户从纵向进入横向模式,反之亦然,始终需要设备旋转 .
-
如果用户锁定了设备方向,则根本不起作用 .
-
当从横向模式转换回来,并且用户已将其设备旋转到纵向(在最后一个横向视图中)时,纵向视图's interface will be locked to a '横向'布局,直到用户重新旋转其设备(所以目前我只是显示叠加旋转设备,但它已经旋转......对用户来说非常烦人) . 现在有了上述实施的大量问题 .
Would love to be able to:
-
强制在手机上为当前视图更改方向 .
-
为视图的推/弹之间强制视图设置首选布局 .
我在这里和Apple Dev论坛上看了很多其他解决方案,但似乎没有人能够解决这个问题,或者两个视图之间的这种方向错误仍然存在 .
感谢您的帮助或指点!没有建议可以打折:D
- 编辑::
解决方案感谢@ leo-natan !!
因此,不要试图强制改变视图的方向 . 只需推送一个新的模态视图 . 这迫使改变 . 您仍需要使用上方的方向代码来管理旋转 .
那么我现在在HomeViewController中有什么:
LandscapeViewController * viewController = [[[LandscapeViewController ViewController alloc] init] autorelease];
UINib * nib = [UINib nibWithNibName:@"NavigationController" bundle:nil];
NavigationController *navController = [[nib instantiateWithOwner:nil options:nil] objectAtIndex:0];
[navController initWithRootViewController:viewController];
[self presentViewController:navController animated:YES completion:^{
// completion
}];
因此有必要为此模态视图重新添加新的导航控制器 . 另请注意上面'presentViewController'是推动Modal视图的新方法 .
实现了这个重载方法来管理视图控制器:
-(id)initWithRootViewController:(UIViewController *)rootViewController {
self = [super initWithRootViewController:rootViewController];
if(self){
}
return self;
}
Note: 上面没有使用故事板 . 可以通过使用故事板并以相同方式模态地显示视图来解决该问题 .
1 回答
请参阅我的回答here,包括一个测试项目 .
基本上,只有在以模态方式呈现视图控制器时才能强制改变方向 . 例如,某些应用中的媒体播放 . 如果您希望从只能以纵向显示的视图控制器转换为仅以横向显示的视图控制器,则需要进行模式演示 . 推送不起作用 .