幕后iOS风景定位处理

Mat*_*ley 6 landscape frame orientation uiviewcontroller ios

任何人都可以详细解释为什么iOS在框架和转换方面处理它的横向方向吗?

我所说的是通过在各种View Lifecycle方法中记录视图描述来显示以下行为:

viewDidLoad: "UIView: 0x1edb5ba0; frame = (0 0; 568 320); autoresize = W+H; layer = <CALayer: 0x1edb5c50>"

viewWillAppear: "UIView: 0x1edb5ba0; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x1edb5c50>"

viewDidAppear: "UIView: 0x1edb5ba0; frame = (0 0; 320 568); transform = [0, 1, -1, 0, 0, 0]; autoresize = W+H; layer = <CALayer: 0x1edb5c50>"
Run Code Online (Sandbox Code Playgroud)

这种影响是微妙的,但非常有趣.

例如,我使用Initial Interface Orientation启动我的应用程序,并将Supported Interface Orientations设置为"Landscape(右主页按钮)"

然后我显示我的rootViewController,如下所示:

self.viewController = [[MyViewController alloc] initWithNibName:nil bundle:nil];
self.window.rootViewController = self.viewController;
Run Code Online (Sandbox Code Playgroud)

这个.xib的方向设置为Landscape,它的框架设置为0,0,568,320.它显示正确,我可以触摸屏幕上的所有点.

当我提出这样的子视图时,问题就出现了:

SomeView *someView = [[SomeView alloc] initWithFrame:self.view.frame];
[self.view addSubview:someView];
Run Code Online (Sandbox Code Playgroud)

此时,self.view.frame报告为(0 0; 320 568),self.view.transform报告为transform = [0,1,-1,0,0,0].最好的情况,最终结果是我只能触摸我刚才显示的视图的左侧320px,最糟糕的情况是视图的布局被屠杀.

感谢各种SO问题,我了解到正确的方法如下:

SomeView *someView = [[SomeView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:someView]
Run Code Online (Sandbox Code Playgroud)

我没学到的是为什么,我对此非常好奇.

我更加好奇的是为什么视图在实例化和显示期间被操纵.

这已经有一段时间了,因为我已经与一个仅景观应用程序纠结,但由于某种原因,我认为当前的实现与早期版本的iOS不同,这是正确的吗?

pri*_*nce 0

根据苹果公司的说法,默认情况下,应用程序支持纵向和横向方向。当基于 iOS\xe2\x80\x93 的设备的方向发生变化时,系统会发出 UIDeviceOrientationDidChangeNotification 通知,让任何感兴趣的各方知道发生了变化。默认情况下,UIKit 框架会侦听此通知并使用它来自动更新界面方向。这意味着,除了少数例外,您根本不需要处理此通知。

\n\n

必须给出边界而不是框架的原因很简单。一旦应用程序处于横向视图,与纵向视图相比,其宽度和高度就会互换。所以这会导致腐败行为。但是在给出边界时,它会考虑视图的方向并相应地采用高度和宽度。

\n\n

当您的视图控制器非常靠近视图层次结构的顶部(或者实际上在顶部)时,您会发现您获得了宽度和高度的“交换”效果。交换通常表现在框架上,而不是视图的边界上。这是因为边界实际上是应用于框架的一些转换 - 有时这些转换包括 90 度旋转(由于设备处于横向模式)。\n请注意,检查框架属性的确切时间也很重要。如果您在视图加载之后但在屏幕上显示之前检查该属性,则可能会得到“错误”结果。

\n