问题: A 有一个应用程序的不同部分同时使用横向模式(锁定)和纵向模式(锁定)。现在我有一个可行的解决方案,但它似乎不正确并且确实有它自己的问题。
理想情况下,我很想强制改变方向。如果需要,甚至考虑进行视图转换。
App基本流程:
- HomeView(纵向)(其中有一些子推送视图也是纵向并锁定到该视图)。
- LandscapeView (Landscape) (其中有 5 个被推送的子视图也是横向的)
笔记:
- HomeView 有一个到 LandscapeView 的链接
- LandscapeView 可以回到 HomeView
- 在 LandscapeView 子视图结束时,它返回到 HomeView
显示不同视图方向的基本图像。(线条表示应用程序的流程,图像的方向表示每个屏幕应该如何)
当前使用以下实现调用/设置视图是否处于纵向模式或横向模式,通过 [setLockedToPortait:YES] (用于纵向视图)等。
如果设备旋转,这个术语会查询从 iOS 使用的界面方向。
现在对于转到 LandscapeView 的情况,我在普通视图的顶部显示一个临时视图,要求使用将他们的手机旋转到横向。(从横向视图返回 HomeView 时也会显示一个临时视图)
因此,一旦用户旋转了他们的设备,它将触发正确的方向,然后临时视图将隐藏。
如果用户此时将手机旋转回纵向,它仍将被锁定为横向,因此不会触发另一个视图旋转(也不会出现临时视图或任何东西)
当前实施代码::
// ---------------------- 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);
}
当前问题:
- 为用户从纵向进入横向模式加载视图后,始终需要设备旋转,反之亦然。
- 如果用户锁定了设备方向,这将根本不起作用。
- 当从横向模式转换回来时,并且用户已经将他们的设备旋转到纵向(在最后一个横向视图中),纵向视图的界面将被锁定为“横向”布局,直到用户重新旋转他们的设备(所以目前我我只是显示覆盖以旋转设备,但它已经旋转了……对用户来说非常烦人)。上述实现目前存在巨大问题。
希望能够:
- 强制在手机上更改当前视图的方向。
- 为在视图的推送/弹出之间强制的视图设置首选布局。
我在这里和 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”是推送模态视图的新方法。
为管理视图控制器实现了这个重载方法:
-(id)initWithRootViewController:(UIViewController *)rootViewController {
self = [super initWithRootViewController:rootViewController];
if(self){
}
return self;
}
注意:以上没有使用情节提要。该问题可以通过使用情节提要和以相同方式模态显示视图来解决。