UI随设备旋转从iOS6到iOS8的适配策略

- (void)statusBarOrientationChange:(NSNotification *)notification

{

    WClassAndFunctionName;

    UIInterfaceOrientation oriention = [UIApplication sharedApplication].statusBarOrientation;

    [self adaptUIBaseOnOriention:oriention];

}

一般情况下,关于屏幕旋转的适配用view自带的autoresizingmask属性就能轻松适配宽度以及边距,而且从iOS6到iOS8通吃。不过,前提是“一般情况下”。当你需要在横屏与竖屏状态下让你封装的view有不同的布局,那autoresizingMask属性就显得力不重新了。这也是本文要解决的主要问题。

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

开始检测视图旋转。

在init方法中注册通知

- (void)registerListeningDeviceOriention

{

    [[NSNotificationCenter defaultCenter] addObserver:self

                                             selector:@selector(statusBarOrientationChange:)

                                                 name:UIApplicationDidChangeStatusBarOrientationNotification

                                               object:nil];

}

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


1

2

3

4

5

6

- (void)statusBarOrientationChange:(NSNotification *)notification

{

    WClassAndFunctionName;

    UIInterfaceOrientation oriention = [UIApplication sharedApplication].statusBarOrientation;

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

}

然而,事情并不是那么顺利跟想当然的!当你满怀信心地在adaptUIBaseOnOriention方法中根据oriention做布局后会发现,iOS8跑出来的效果很完美,而非iOS8版本却乱七八糟。很多时候自定义view(以下简称superview)的subviews的布局要依赖于superview的size。所以一旦superview的frame没有适配好,那看起来就乱七八糟了!为什么会出现上述差异呢?根本原因是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));

}

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

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

传送门:

http://www.cnblogs.com/wengzilin/p/4236582.html

时间: 2024-10-05 01:30:36

UI随设备旋转从iOS6到iOS8的适配策略的相关文章

【原】UI随设备旋转从iOS6到iOS8的适配策略

- (void)statusBarOrientationChange:(NSNotification *)notification { WClassAndFunctionName; UIInterfaceOrientation oriention = [UIApplication sharedApplication].statusBarOrientation; [self adaptUIBaseOnOriention:oriention]; } 一般情况下,关于屏幕旋转的适配用view自带的au

iOS设备旋转支持横屏

ios设备支持旋转的方法: 1.修改工程的info.plist中"Supported interface orientations"的值(一般在工程的Taget-> General -> Deployment Info -> Device Orientation处打钩来选择设备支持). 2.实现工程的AppDelegate文件中的(application:supportedInterfaceOrientationsForWindow:)方法,在此方法中返回程序支持的方

设备旋转,创建水平模式布局--Android studio

1.在项目工具窗口中,右键单击res目录后选择new--Android resource directory菜单项. 2.从资源类型Resource type列表中选择layout,保持Source Set的main选项不变. 3.选中待选资源特征列表中的Orientation,然后单击>按钮移动至右边已选资源特征区域. 4.确认选中的Screen Orientation下拉列表的Landscape选项,并确保目录名显示为layout-land,点击OK创建res/layout-land目录.

iOS8 屏幕适配问题。

最近在做关于iPhone6,6+,以及你给iOS8 的适配. 在此做一小结. iOS多屏幕中适配的实现设计到以下几个方面. 1.宏定义: 原理:通过定义宏定义获取屏幕的宽高,从而可以动态定位视图中元素的大小和位置. 适用于: 屏幕尺寸较少,内容显示单一,满足于元素放大.缩小等较单一的呈现. 缺点:随着iPhone设备种类的增多,屏幕尺寸趋于多样化,此方式的实现变的复杂. 若需求为,针对不同的平布尺寸,屏幕显示的内容多少不同, 方式不同, 这样的需求,宏定义实现起来也是相当的复杂. 2.autol

iOS6 / iOS7 状态栏高度适配

问题原因:iOS7的状态栏(status bar)不再占用单独的20px,所以假设你在iOS6上的界面布局是正常的,那么到了iOS7上就会变成以下这个样子:             左边是iOS6界面布局,右边是iOS7界面布局.这时有人会想着把iOS7界面上控件总体向下移动20px,可是当Interface Builder Document改成Xcode 4.6时又变成了例如以下情况:             界面不会由于你在不同的Interface Builder Document值下设置不

UI移动设备屏幕知识

今天同学给我了一个设计UI的软件,其实我是一头雾水的,有点孤陋寡闻了,设计UI还有这样的软件.百度了下,看见这篇文章还是很有收获的,原来UI还是一门如此高深的学问.把这篇文章和大家一起分享吧,希望你们能够得到一些帮助. 1.了解几个概念 (1)分辨率.分辨率就是手机屏幕的像素点数,一般描述成屏幕的“宽×高”,安卓手机屏幕常见的分辨率有480×800.720×1280.1080×1920等.720×1280表示此屏幕在宽度方向有720个像素,在高度方向有1280个像素. (2)屏幕大小.屏幕大小是

XCODE shouldAutorotateToInterfaceOrientation 对于不同版本 设备旋转不同方向时 视图的相应旋转方向的实现

对于版本号不同的设备,旋转时视图的要做出相应的旋转,那么版本不同,代码的实现是如何的,如何对旋转方向做出限制?下面是小编的个人看法! //版本号为3.5 -5.0 -(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { //   return NO; //不支持随设备多的旋转而旋转: return(toInterfaceAorientation != UIInte

关于监听与控制设备旋转全解析(UIDeviceOrientationDidChangeNotification)

一类情况: 初始化app的方向,比如只支持横屏或者竖屏.下面举例只支持竖屏的案例 在app的属性里面手动设置 上面标注了该app支持的方向种类,要是在app里支持Portrait方向,还需要添加以下代码 二类情况: 上面的代码表明app支持了两个方向,Protrait 和PortraitUpsideDown,如果我要求在app在某个 方向的时候禁止屏幕旋转,该怎么做呢? 在swift中禁止当前屏幕旋转 UIDevice.currentDevice().endGeneratingDeviceOri

【学习ios之路:UI系列】(UISearchBar,UISearchDisplayController) 和UISearchController(iOS8新特性)

1.UISearchBar(效果如下:) ①创建UISearchBar对象 //初始化,定义frame UISearchBar *bar = [[UISearchBar alloc] initWithFrame:CGRectMake (0, 50, self.view.frame.size.width, 80)]; //添加到控制器的视图上 [self.view addSubview:bar]; ②UISerachBar的属性 //autocapitalizationType:包含4种类型,但是