5

问题: 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;
}

注意:以上没有使用情节提要。该问题可以通过使用情节提要和以相同方式模态显示视图来解决。

4

1 回答 1

7

在这里查看我的答案,包括一个测试项目。

基本上,只能在模态显示视图控制器时强制改变方向。例如,某些应用程序中的媒体播放。如果您希望从只能以纵向呈现的视图控制器过渡到只能以横向呈现的视图控制器,则需要模态呈现。推送将不起作用。

于 2013-09-27T02:58:46.247 回答