为什么ViewController的初始方向不是横向的?

时间:2022-06-28 21:09:03

I'm making an app that only supports landscape mode of an iOS device. So I have set it to only return YES for UIInterfaceOrientationLandscapeRight and UIInterfaceOrientationLandscapeLeft in shouldAutorotateToInterfaceOrientation: and set the initial orientation in Info.plist to UIInterfaceOrientationLandscapeRight. The app is displaying fine.

我正在做一个只支持iOS设备的横向模式的应用。因此,我将它设置为只返回对uiinterfaceorientationorientationdesign和uiinterfaceorientation园林中的shouldAutorotateToInterfaceOrientation:并设置信息的初始化方向。plist UIInterfaceOrientationLandscapeRight。这个应用程序显示得很好。

The problem is that the coordinate system is not in landscape until the view is finished loading (I'm not particularly sure here when it is being applied correctly). What I know is that it changes to the correct coordinate space when it calls the: shouldAutorotateToInterfaceOrientation upon launch. The problem is that when both viewDidLoad and initWithCoder: are called it is in the wrong coordinate space, before shouldAutorotate....

问题是,在视图完成加载之前,坐标系统不处于横向状态(我在这里不是特别确定何时它被正确地应用)。我所知道的是,它在发射时调用:shouldAutorotateToInterfaceOrientation时,会改变到正确的坐标空间。问题是,当viewDidLoad和initWithCoder:被称为错误的坐标空间,之前shouldAutorotate ....

What I mean is that if I set a view to the full width of the screen with CGRectMake(0, 0, 480, 320) (instead of using self.view.frame or something) it is borked when the coordinate spaces are rotated "corrected". The views created in viewDidLoad have a rotation applied to them so they are wrong. This makes setting up views in those methods a pain and really illogical. I'm guessing that this is an issue with how orientations are handled. Why does it behave like this? I have told it in every way possible that I only want landscape position. Can this be something with Interface builder and properties there?

我的意思是,如果我使用CGRectMake(0,0,480,320)(而不是使用self.view.frame或其他工具)将视图设置为屏幕的全宽,那么当坐标空间被“纠正”时,它就会被填充。viewDidLoad中创建的视图有一个旋转应用于它们,因此它们是错误的。这使得在这些方法中设置视图非常困难,而且非常不合逻辑。我猜这是一个关于朝向如何处理的问题。为什么它会这样?我用各种可能的方式告诉它,我只想要景观位置。这可以是界面构建器和属性吗?

This is using a standard UIViewController. The new views are however also loaded from .xib files in viewDidLoad. Could this be the issue?

这是使用一个标准的UIViewController。但是新的视图也从viewDidLoad的.xib文件中加载。这是问题所在吗?

3 个解决方案

#1


7  

Support for orientation changes is something that all iOS developers struggle with at one time or another. It's often confusing and frustrating. Here's a rule of thumb which will handle 95% of all orientation issues:

对方向变化的支持是所有iOS开发人员都曾遇到过的问题。这常常令人困惑和沮丧。这里有一条经验法则可以处理95%的定向问题:

Orientation related interface changes (such as frame resizing) don't happen until viewWillAppear:. Until then, your view will be in portrait mode even if you only support landscape in your app or your app is already in landscape mode.

在viewWillAppear:之前,不会发生与方向相关的接口更改(例如帧大小)。在此之前,您的视图将处于竖屏模式,即使您只支持应用程序中的横向模式,或者您的应用程序已经处于横向模式。

Since viewDidLoad: occurs before viewWillAppear:, orientation layout changes haven't occured yet. So, doing any of the following in viewDidLoad will often have wonky results (depending on how the view's autoResize is set):

因为viewDidLoad:发生在viewWillAppear:之前,所以还没有发生方向布局更改。因此,在viewDidLoad中执行以下任何一种操作通常会产生不稳定的结果(取决于如何设置视图的自动大小):

  • inserting a layer (such as a gradient) inside a view with a frame that is equal to the view's bounds. The layer inserted will always be the size of the view in portrait mode. If that view stretches when rotating to landscape view, your layer will be smaller than the view.
  • 在视图中插入一个层(例如渐变),其框架等于视图的边界。所插入的层将始终为纵向模式下的视图的大小。如果视图在旋转到横向视图时拉伸,你的层将比视图小。
  • trying to determine the size of a table view and using that frame for some other view
  • 尝试确定一个表视图的大小,并将该框架用于其他视图
  • manually adding a child view controller and using a container view's frame to determine the child view controller's view frame.
  • 手动添加子视图控制器,并使用容器视图的框架来确定子视图控制器的视图框架。

#2


1  

I was just reading over the UIViewController documentation today, and I remember reading about this.

我今天刚刚读了UIViewController文档,我记得读过这个。

From the “Handling View Rotations” overview section:

从“处理视图旋转”概述部分:

By default, the UIViewController class displays views in portrait mode only. To support additional orientations, you must override the shouldAutorotateToInterfaceOrientation: method and return YES for any orientations your subclass supports. If the autoresizing properties of your views are configured correctly, that may be all you have to do. However, the UIViewController class provides additional hooks for you to implement additional behaviors as needed.

默认情况下,UIViewController类只显示纵向模式下的视图。要支持其他方向,必须重写shouldAutorotateToInterfaceOrientation:方法,并为子类支持的任何方向返回YES。如果视图的自动调整属性配置正确,这可能就是您所要做的。但是,UIViewController类为您提供了附加的钩子,以便根据需要实现附加的行为。

Note: At launch time, applications should always set up their interface in a portrait orientation. After the application:didFinishLaunchingWithOptions: method returns, the application uses the view controller rotation mechanism described above to rotate the views to the appropriate orientation prior to showing the window.

注意:在启动时,应用程序应该始终设置它们的界面在一个纵向。应用程序:didFinishLaunchingWithOptions:方法返回,应用程序使用上面描述的视图控制器旋转机制,在显示窗口之前将视图旋转到适当的方向。

http://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40006926-CH3-SW57

http://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html / / apple_ref / doc / uid / TP40006926-CH3-SW57

One thing I can think of that might be causing you extra trouble is if you’re setting autoresizingMask options on your subviews. Could make predicting what will happen when the view is rotated and resized very difficult if all your numbers are wrong.

我能想到的一件事可能会给你带来额外的麻烦,如果你在你的子视图上设置了autoresizingMask选项。如果所有的数字都是错误的,那么就很难预测视图旋转和调整大小时会发生什么。

If you're using custom UIVIews, you might want to override layoutSubviews: to handle the different times when it may be necessary to layout the subviews again (or when you call setNeedsLayout).

如果您正在使用自定义的uiview,您可能想要覆盖layoutSubviews:以处理可能需要重新布局子视图的不同时间(或者当您调用setNeedsLayout布局时)。

#3


0  

You can reorder the Supported interface orientations in [project]-info.plist file, set item 0 value to Landscape (right home button).

您可以在[项目]信息中重新排序所支持的接口朝向。plist文件,将项目0设置为Landscape(右home按钮)。

#1


7  

Support for orientation changes is something that all iOS developers struggle with at one time or another. It's often confusing and frustrating. Here's a rule of thumb which will handle 95% of all orientation issues:

对方向变化的支持是所有iOS开发人员都曾遇到过的问题。这常常令人困惑和沮丧。这里有一条经验法则可以处理95%的定向问题:

Orientation related interface changes (such as frame resizing) don't happen until viewWillAppear:. Until then, your view will be in portrait mode even if you only support landscape in your app or your app is already in landscape mode.

在viewWillAppear:之前,不会发生与方向相关的接口更改(例如帧大小)。在此之前,您的视图将处于竖屏模式,即使您只支持应用程序中的横向模式,或者您的应用程序已经处于横向模式。

Since viewDidLoad: occurs before viewWillAppear:, orientation layout changes haven't occured yet. So, doing any of the following in viewDidLoad will often have wonky results (depending on how the view's autoResize is set):

因为viewDidLoad:发生在viewWillAppear:之前,所以还没有发生方向布局更改。因此,在viewDidLoad中执行以下任何一种操作通常会产生不稳定的结果(取决于如何设置视图的自动大小):

  • inserting a layer (such as a gradient) inside a view with a frame that is equal to the view's bounds. The layer inserted will always be the size of the view in portrait mode. If that view stretches when rotating to landscape view, your layer will be smaller than the view.
  • 在视图中插入一个层(例如渐变),其框架等于视图的边界。所插入的层将始终为纵向模式下的视图的大小。如果视图在旋转到横向视图时拉伸,你的层将比视图小。
  • trying to determine the size of a table view and using that frame for some other view
  • 尝试确定一个表视图的大小,并将该框架用于其他视图
  • manually adding a child view controller and using a container view's frame to determine the child view controller's view frame.
  • 手动添加子视图控制器,并使用容器视图的框架来确定子视图控制器的视图框架。

#2


1  

I was just reading over the UIViewController documentation today, and I remember reading about this.

我今天刚刚读了UIViewController文档,我记得读过这个。

From the “Handling View Rotations” overview section:

从“处理视图旋转”概述部分:

By default, the UIViewController class displays views in portrait mode only. To support additional orientations, you must override the shouldAutorotateToInterfaceOrientation: method and return YES for any orientations your subclass supports. If the autoresizing properties of your views are configured correctly, that may be all you have to do. However, the UIViewController class provides additional hooks for you to implement additional behaviors as needed.

默认情况下,UIViewController类只显示纵向模式下的视图。要支持其他方向,必须重写shouldAutorotateToInterfaceOrientation:方法,并为子类支持的任何方向返回YES。如果视图的自动调整属性配置正确,这可能就是您所要做的。但是,UIViewController类为您提供了附加的钩子,以便根据需要实现附加的行为。

Note: At launch time, applications should always set up their interface in a portrait orientation. After the application:didFinishLaunchingWithOptions: method returns, the application uses the view controller rotation mechanism described above to rotate the views to the appropriate orientation prior to showing the window.

注意:在启动时,应用程序应该始终设置它们的界面在一个纵向。应用程序:didFinishLaunchingWithOptions:方法返回,应用程序使用上面描述的视图控制器旋转机制,在显示窗口之前将视图旋转到适当的方向。

http://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40006926-CH3-SW57

http://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html / / apple_ref / doc / uid / TP40006926-CH3-SW57

One thing I can think of that might be causing you extra trouble is if you’re setting autoresizingMask options on your subviews. Could make predicting what will happen when the view is rotated and resized very difficult if all your numbers are wrong.

我能想到的一件事可能会给你带来额外的麻烦,如果你在你的子视图上设置了autoresizingMask选项。如果所有的数字都是错误的,那么就很难预测视图旋转和调整大小时会发生什么。

If you're using custom UIVIews, you might want to override layoutSubviews: to handle the different times when it may be necessary to layout the subviews again (or when you call setNeedsLayout).

如果您正在使用自定义的uiview,您可能想要覆盖layoutSubviews:以处理可能需要重新布局子视图的不同时间(或者当您调用setNeedsLayout布局时)。

#3


0  

You can reorder the Supported interface orientations in [project]-info.plist file, set item 0 value to Landscape (right home button).

您可以在[项目]信息中重新排序所支持的接口朝向。plist文件,将项目0设置为Landscape(右home按钮)。