Why RootViewController's view is rotated Automatically by System when the app first loaded?

本文深入解析了iOS设备旋转时,UI窗口如何通过应用旋转转换来调整用户界面,并通过实例展示了从肖像到横屏旋转时UI元素的变换过程。同时提供了Adam Lockhart的临时解决方案,以及推荐的正确处理方式:不直接对顶级视图应用自定义转换,而是将其作为可转换的子视图,以避免界面旋转时的重新设置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Your app has a UIWindow, which contains your root view controller's view, which contains the button:

  • UIWindow
    • your root view
      • UIButton

What you didn't understand is that the UIWindow rotates the user interface by applying a rotation transform to your root. Take a look at the view hierarchy when the interface is in landscape-left orientation:

(lldb) po [[UIApp keyWindow] recursiveDescription]
(id) $1 = 0x0922ee80 <UIWindow: 0x942c280; frame = (0 0; 768 1024); layer = <UIWindowLayer: 0x942c380>>
   | <UIView: 0x9432b30; frame = (20 0; 748 1024); transform = [0, -1, 1, 0, 0, 0]; autoresize = W+H; layer = <CALayer: 0x9432be0>>
   |    | <UIRoundedRectButton: 0x942f7a0; frame = (476 352; 73 44); opaque = NO; layer = <CALayer: 0x942f8c0>>
   |    |    | <UIGroupTableViewCellBackground: 0x94300b0; frame = (0 0; 73 44); userInteractionEnabled = NO; layer = <CALayer: 0x9430180>>
   |    |    | <UIImageView: 0x9430af0; frame = (1 1; 71 43); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x9431340>>
   |    |    | <UIButtonLabel: 0x94319c0; frame = (12 12; 49 19); text = 'Button'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x9431d10>>
 

See how the UIWindow's subview (UIView: 0x942c380) has a transform of [0, -1, 1, 0, 0, 0]? That transform rotates your top-level view 90˚ counter-clockwise. If you rotate your device (or the simulator) to landscape-right orientation, you will see that the transform becomes [0, 1, -1, 0, 0, 0]:

(lldb) po [[UIApp keyWindow] recursiveDescription]
(id) $2 = 0x07436d90 <UIWindow: 0x942c280; frame = (0 0; 768 1024); layer = <UIWindowLayer: 0x942c380>>
   | <UIView: 0x9432b30; frame = (0 0; 748 1024); transform = [0, 1, -1, 0, 0, 0]; autoresize = W+H; layer = <CALayer: 0x9432be0>>
   |    | <UIRoundedRectButton: 0x942f7a0; frame = (476 352; 73 44); opaque = NO; layer = <CALayer: 0x942f8c0>>
   |    |    | <UIGroupTableViewCellBackground: 0x94300b0; frame = (0 0; 73 44); userInteractionEnabled = NO; layer = <CALayer: 0x9430180>>
   |    |    | <UIImageView: 0x9430af0; frame = (1 1; 71 43); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x9431340>>
   |    |    | <UIButtonLabel: 0x94319c0; frame = (12 12; 49 19); text = 'Button'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x9431d10>>

When you reset the view's transform, you're losing the rotation, so the view reverts to its “default” rotation of 0˚, which is the portrait rotation.

Adam Lockhart's answer will fix this temporarily, but if the user rotates the device, the UIWindow will reset your view's transform, losing the translation you applied.

The correct way to handle this is to not apply your own transform to your top-level view. Give your top-level view a subview that you can transform, and put your button inside that:

  • UIWindow
    • your root view
      • your transformable view
        • UIButton
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值