UI随设备旋转从ios6到ios8的适配

本文详细介绍了如何在自定义视图中检测屏幕旋转事件,并根据不同iOS版本的特性调整布局,确保视图在横屏与竖屏状态下都能保持良好的显示效果。通过在初始化方法中注册通知监听屏幕旋转,以及在旋转事件发生时获取正确的设备方向和尺寸信息,实现了自定义视图的动态适配。特别针对iOS8及以上版本与之前的版本在处理旋转事件上的差异,提出了判断设备版本并据此调整布局的解决方案。

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

一般情况下,关于屏幕旋转的适配用view自带的autoresizingmask属性就能轻松适配宽度以及边距,而且从iOS6到iOS8通吃。但是当你需要在横屏与竖屏状态下让你封装的view有不同的布局,那autoresizingMask属性就显得力不从心了。

显然,检测视图旋转事件是必须要做的。一般我们封装一个自定义控件,总是希望调用者可以轻松的调用它,因此检测视图旋转也应该在控件内做。

开始检测视图旋转。

在init方法中注册通知

- (void)registerListeningDeviceOriention

{

    [[NSNotificationCenter defaultCenter] addObserver:self

                                             selector:@selector(statusBarOrientationChange:)

                                                 name:UIApplicationDidChangeStatusBarOrientationNotification

                                               object:nil];

}  }


一旦屏幕产生旋转,则调用statusBarOrientionChange:方法。比如:

- (void)statusBarOrientationChange:(NSNotification *)notification

{

    WClassAndFunctionName;

    UIInterfaceOrientation oriention = [UIApplication sharedApplication].statusBarOrientation;

    [self adaptUIBaseOnOriention:oriention];//比如改变self.frame

}

但事情并不是那么顺利跟想当然的!当你满怀信心地在adaptUIBaseOnOriention方法中根据oriention做布局后会发现,iOS8跑出来的效果很完美,而非iOS8版本却乱七八糟。很多时候自定义view(以下简称superview)subviews的布局要依赖于superviewsize。所以一旦superviewframe没有适配好,那看起来就乱七八糟了!为什么会出现上述差异呢?根本原因是statusBarOrientationChange的触发时机依赖于ios版本。打log后发现,iOS8及以上的版本,statusBarOrientationChange在旋转结束后调用;在iOS8以下的版本,statusBarOrientationChange在旋转前调用。而如果你在statusBarOrientationChange方法中想当然地去读取当前的设备高度跟宽度,那必然产生差异!

总体思路是没错的,下一步就是在statusBarOrientationChange里面对当前的设备方向以及系统版本进行判断,这样才能取到真正的设备高度跟宽度,真正的设备高度宽度对于布局是至关重要的!

CGFloat windowWidth = kDeviceWindowWidth4Panel;//iOS8不用更改

CGFloat windowHeight = kDeviceWindowHeight4Panel;

if (!IsIOS8orAbove) {

    windowWidth = (!kIsDeviceLandscape) ? kDeviceWindowWidth4Panel:kDeviceWindowHeight;

    windowHeight = (!kIsDeviceLandscape) ? kDeviceWindowHeight4Panel:(kDeviceWindowWidth - (IsIOS7orAbove ? 0 : kSystemStatusBarHeight));

}

其实,本质上可以简述为:iOS8windowSize取的是当前时刻的windowSize值,因此可以直接赋值;iOS8以下的windowSize取得是下一时刻旋转后的值,相当于预判了。


最后一点需要注意的地方是,如果需要在statusBarOrientationChange方法中手动改变superviewframe,那请把init方法中的autoresizingMask属性全部注释掉,因为两者是冲突的,尤其是在iOS8以下。因为在iOS8以下本质上是在旋转之前就将所有的subviews的布局更新为旋转后的状态了,这样翻转过去就能正常显示。如果你加了autoresizingMask属性,那系统会根据旋转前最后一刻的状态来适配,这样旋转后就群魔乱舞了。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值