在iPad开发中,横竖屏的视图常常是不同的,例如侧边栏Dock,在横屏时用于屏幕较宽,可以展示足够多的内容,每个按钮都可以展示出标题;而竖屏时Dock应该比较窄,只显示图标不现实按钮标题。
iPad比较重要的知识是不同类型设备的宽高在以点为单位的图形坐标系下固定为768x1024,因此常常利用此值来判断横竖屏。
768、1024、横竖屏判断很常用,可以定义一个公共的常量文件来放这些内容。
【常量和宏的定义】
①在.m文件中,定义变量,加上const,注意指针(例如NSString*)使用的是常量,而不是常量指针。
// 屏幕竖屏时的宽度
const CGFloat HMScreenPW = 768;
// 屏幕横屏时的宽度
const CGFloat HMScreenLW = 1024;
对于指针量的定义:
NSString *const Title = @"Title";
②在.h文件中,使用extern声明上面的变量,利用宏判断横竖屏。
// 屏幕竖屏时的宽度
extern const CGFloat HMScreenPW;
// 屏幕横屏时的宽度
extern const CGFloat HMScreenLW;
#define Lanscape ([UIScreen mainScreen].bounds.size.width == HMScreenLW)
#define Portrait ([UIScreen mainScreen].bounds.size.width == HMScreenPW)
【适配的关键方法】
①屏幕旋转时会调用控制器的方法:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;
通过函数判断横竖屏:
UIInterfaceOrientationIsLandscape(toInterfaceOrientation)
常见用法:
注意在这个方法调用时屏幕旋转还未完成,在这里拿到的宽高将会是错误的(原来的)。
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
// 调用此函数时还未完成旋转,当前高度是旧的
if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) { // 横屏 } else { // 竖屏 } }
在iOS8中,上面的方法已经过期,更新为下面的方法:
注意实现了这个方法上面的方法就失效了,因此为了适配应该用上面的方法。
// 实现了下面的方法上面的过期方法就不会调用了,为了适配应该使用老方法。
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator{ NSLog(@"%@",NSStringFromCGSize(size)); }
②UIView在尺寸被修改后,会调用layoutSubviews方法,可以通过重写此方法,先调用父类方法,然后实现自己的布局逻辑,从而实现Dock等的横竖屏变换。
- (void)layoutSubviews
{
[super layoutSubviews];
// 自己的布局逻辑
}
【复杂视图的切分】
对于一个复杂的视图,常常需要多次切分,然后分别处理,例如下面的视图的切分:
首先整个控制器视图被切分为ContentView和Dock两部分,Dock内部又进行了细分,在竖屏时,Dock应该变窄,下面的所有按钮都是竖着排列,并且不显示标题,如下图所示:
切分完毕后,处理适配就变得简单了。首先屏幕旋转会调用控制器的方法,控制器直接修改Dock尺寸,从而调用了Dock的layoutSubviews方法,Dock在此方法中又对HeadView、Tabbar、Toobar的尺寸进行了修改,又调用了它们各自的layoutSubviews方法,因为只需要在layoutSubviews中处理尺寸改变即可。