代码之家  ›  专栏  ›  技术社区  ›  Pablo Cabrera

iPhone横向常见问题解答和解决方案

  •  18
  • Pablo Cabrera  · 技术社区  · 7 年前

    这里有很多困惑和一组相应的问题,因此如何实现具有适当处理横向/纵向模式自动旋转的iPhone应用程序。当需要以横向模式启动时,尤其难以实现这种应用程序。最常见的观察效果是屏幕上混乱的布局和无法识别触摸的区域。

    简单搜索标记的问题 iphone landscape 揭示在某些情况下出现的这些问题:

    已经提出了一组不同的解决方案,其中一些解决方案包括通过Coregraphics完全自定义动画,而另一些解决方案则建立在观察到从主NIB加载的第一个视图控制器始终显示正确的基础上。

    我花了大量的时间研究这个问题,最终找到了一个不仅是部分解决方案,而且在所有这些情况下都可以工作的解决方案。我打算在这篇CW文章中为其他在景观模式下遇到uiviewcontrollers问题的人提供一种常见问题解答。

    请提供反馈,并结合任何相关的意见,帮助提高本帖的质量。如果您知道任何答案,请随时编辑和发布其他/更好的答案。

    6 回复  |  直到 13 年前
        1
  •  13
  •   Pablo Cabrera    14 年前

    里面有什么 documentation :

    在视图控制器中,重写shouldAutoToInterfaceOrientation:以声明支持的接口方向。每次设备方向更改时,控制器基础结构都会/应该检查此属性。

    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation
    {
       return  (orientation == UIInterfaceOrientationLandscapeRight);
    }
    

    这是视图控制器所需的绝对最小值。如果要以横向模式启动应用程序,则需要将以下键添加到 .plist 文件:

    <key>UIInterfaceOrientation</key>
    <string>UIInterfaceOrientationLandscapeRight</string>
    

    Apple建议以“横向”右模式启动仅横向应用程序(请参见 the HIG 在用户体验指导原则下,立即启动)。

    文档中没有的内容:

    一点背景:

    每次尝试加载不同于从主NIB加载的视图控制器时,都不会询问视图控制器支持的接口方向,也不会正确设置其帧。只有绑定到窗口的第一个视图控制器才能正确布局。

    其他人建议使用连接到主窗口的“masterviewcontroller”,其他控制器将其视图作为子视图添加到主窗口中,而不是直接连接到窗口中。虽然我发现这个解决方案是一个可行的选择,但在添加到这些子视图中的模态视图控制器的情况下,它不能正常工作。还有一个问题,如果有的话 一些 应该能够自动旋转的子视图(主控制器将阻止的)。

    使用未记录的API强制特定的接口方向也不是一个选项。

    解决方案:

    到目前为止,我发现的最佳解决方案是修改“masterviewcontroller”解决方案。不是使用自定义的“MasterViewController”,而是 UINavigationController 使用隐藏导航栏和隐藏选项卡栏。如果从该控制器的导航堆栈中推/弹出所有其他视图,将正确管理该堆栈上控制器的自动旋转。

    模态控制器通过 presentModalViewController:animated: 从上的任何视图控制器 ui导航控制器 的导航堆栈将旋转并以正确的布局呈现。如果希望模态视图控制器可旋转到与父视图控制器不同的方向,则需要从 shouldAutorotateToInterfaceOrientation 方法 起源 控制器,同时显示模态视图。为了在模态控制器解除时正确地恢复接口方向,需要确保 应注意面间方向 在调用前返回父控制器的所需方向 dismissModalViewController:animated: . 你可以用私人的 BOOL 在视图控制器上进行管理(例如 BOOL isModalMailControllerActive_ )

    我将很快添加一段示例代码,现在只是晚了。请告诉我是否还有任何悬而未决的问题或关于这篇文章的任何不清楚之处。随时编辑和改进。

        2
  •  7
  •   Guntis Treulands    14 年前

    我对iOS应用程序有一个有趣的要求:

    主视图控制器只能是横向的,但所有其他(可以从主视图推)都可以是横向和纵向的。

    当我推到一个新的视图控制器,然后旋转到肖像-和弹出回来-主视图不再是景观问题。同时-开放应用,它不在景观中。

    为了保持主视图控制器的横向,无论从哪个方向弹出/推,我都做了以下操作:(在视图中会出现:)

    //set statusbar to the desired rotation position
    [[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationLandscapeLeft animated:NO];
    
    //present/dismiss viewcontroller in order to activate rotating.
    UIViewController *mVC = [[[UIViewController alloc] init] autorelease];
    [self presentModalViewController:mVC animated:NO];
    [self dismissModalViewControllerAnimated:NO];
    

    希望它能帮助别人!

    P.S.在SDK3.2.5 iOS 5.0.1上测试。

    另外,感谢您提供本常见问题解答中的所有信息!

        3
  •  3
  •   MyCSharpCorner    14 年前

    对于第二个要点,如果您希望使用pushviewcontroller从仅纵向视图转到仅横向视图,我发现的一个简单方法是将以下代码放入推送控制器的viewdidLoad中:

    UIViewController *viewController = [[UIViewController alloc] init];
    [self presentModalViewController:viewController animated:NO];
    [self dismissModalViewControllerAnimated:NO];
    [viewController release];
    
        4
  •  2
  •   Timo    15 年前

    我想添加到约翰内斯的答案中(使用uinavigationController作为主视图控制器)。

    我发现的缺点是,新推到主VC导航堆栈上的视图控制器不能调整为任何先前的方向更改。简而言之,已经在堆栈上的VCS被旋转,从中显示的模态视图控制器也被旋转,但是新添加的VCS 旋转。

    在找到一个有效的方法之前,我尝试了很多技巧来解决这个问题。大多数仅适用于PushView控制器:动画设置为“是”。

    为了彻底解决这个问题,我将 UINagivationController 并覆盖 pushViewController:animated: 如下:

    - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
    {
        // Correctly autoOrient the given view controller
        [self presentModalViewController:viewController animated:NO];
        [self dismissModalViewControllerAnimated:NO];
    
        // Push it as normal (now in its correct orientation)
        [super pushViewController:viewController animated:animated];
    }
    

    临时(并且完全不可见)显示视图控制器允许它接收其方向更新。然后可以将其按正确的方向推到导航堆栈上。

    如果这对你有用,请告诉我。所有的更新和改进都非常欢迎!

    最后,我强烈推荐约翰内斯的轮换管理方法。

    编辑:从堆栈弹出视图控制器时更新

    似乎所有与popviewcontroller相关的选择器在使用动画执行时都会疯狂:是的。具体来说,视图控制器的动画显示方向错误。您可以使用animated:no,并将此类动画的使用限制为层次结构中更深层的其他uinavigationcontrollers(即推到根导航控制器堆栈上的那些)。

    任何意见都非常感谢。

        5
  •  2
  •   Will Marsh    13 年前

    我正在开发一个iPad应用程序,它可以在启动时垂直滚动一系列项目的图库视图。在横向模式中,共有4个项目。肖像画里有三个。当转动ipad方向时,应该刷新画廊,让物品在屏幕上整齐地排列。然后我双击一个项目,向下钻取到该项目的模式视图。然后我就用那个东西。最后,我放弃了模态视图。

    在刷新或方向更改期间,库视图根据屏幕宽度(或高度)和uiviewController.InterfaceOrientation中的当前方向计算要显示的项目数。

    我很难让这个正常工作。有时在我取消模式对话框后,它在横向方向上只显示两个项目。

    起初,我使用uiviewcontroller.view.frame.size值来计算画廊项目的数量。当模式视图被取消时,此帧大小不正确,例如宽度和高度被反转,即使在显示模式对话框时方向没有改变。

    我切换到使用应用程序委托([[uiapplication sharedaplication]delegate]]并使用window.frame.size计算要显示的库项目数。window.frame.size在方向更改和模式对话框下保持正确。库项现在显示正确。

        6
  •  -3
  •   Hiren Patel    13 年前

    这将起作用…

    UIWindow *window = [[UIApplication sharedApplication] keyWindow];
        UIView *view = [window.subviews objectAtIndex:0];
        [view removeFromSuperview];
        [window addSubview:view];
    
    推荐文章