適配屏幕其實很簡單,但爲了保持兼容性以及寫的代碼的通用性,以及最小的改動代碼,本人按照以下的一種方式來適配,能夠一勞永逸.app
1. 先定義幾個宏,分辨表示應用能夠使用區域的高度,屏幕可用區域的高度,屏幕的寬度ide
2. 再看看以下圖的一些描述ui
3. 接下來看看適配的代碼如何寫spa
#import "RootViewController.h"
#define iOS7 ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7 ? YES : NO)
#define APP_HEIGHT [UIScreen mainScreen].applicationFrame.size.height
#define SCR_HEIGHT [UIScreen mainScreen].bounds.size.height
#define SCR_WIDTH [UIScreen mainScreen].bounds.size.width
static int STATUS_HEIGHT = 0;
static int EFFECT_HEITHG = 0;
static int OFFSET_HEIGHT = 0;
static int NAV_HEIGHT = 0;
@implementation RootViewController
+ (void)initialize
{
if (self == [RootViewController class])
{
if (iOS7)
{
STATUS_HEIGHT = 20;
EFFECT_HEITHG = APP_HEIGHT;
OFFSET_HEIGHT = 20;
NAV_HEIGHT = 44;
}
else
{
STATUS_HEIGHT = 0;
EFFECT_HEITHG = APP_HEIGHT;
OFFSET_HEIGHT = 0;
NAV_HEIGHT = 0;
}
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// 爲了適配簡單,任何view的高度都加上一個修正的偏移量
UIView *testView = [[UIView alloc] initWithFrame:\
CGRectMake(0, 0 + OFFSET_HEIGHT + NAV_HEIGHT,
100, 100)];
testView.backgroundColor = [UIColor redColor];
[self.view addSubview:testView];
// 爲了適配簡單,任何view的高度都加上一個修正的偏移量,下面是用來計算距離底部有多大空間的
UIView *bottomView = [[UIView alloc] initWithFrame:\
CGRectMake(0, OFFSET_HEIGHT + EFFECT_HEITHG - 100,
100, 100)];
bottomView.backgroundColor = [UIColor greenColor];
[self.view addSubview:bottomView];
}
@end
看效果圖:code
小結:blog
1. 用最少的代碼來適配iOS6與iOS7的橫屏it
2. 有效屏幕區域與偏移量修正值很關鍵io
附錄:table
iOS6 與 iOS7 在初始化view的時候一個給了WhiteColor當背景,一個給了clearColor當背景,爲了兼容性,請初始化View的時候明確初始化背景顏色類型,視圖控制器在初始化的時候也給設置一個明確的背景色.class
相關注釋:
/*
4寸屏幕(iOS6 iOS7)
APP_HEIGHT 548
SCR_HEIGHT 568
SCR_WIDTH 320
在iOS6中CGRectMake(0, 0, 100, 100)座標在狀態欄如下的20處
*/
/*
3寸屏幕(iOS6 iOS7)
APP_HEIGHT 460
SCR_HEIGHT 480
SCR_WIDTH 320
在iOS6中CGRectMake(0, 0, 100, 100)座標在狀態欄如下的20處
*/
/*
iOS 6
STATUS_HEIGHT = 0
EFFECT_HEITHG = APP_HEIGHT
OFFSET_HEIGHT = 0
iOS 7
STATUS_HEIGHT = 20
EFFECT_HEIGHT = APP_HEIGHT
OFFSET_HEIGHT = 20
*/
更好的適配方式:
1、沒有包裝任何 導航控制器 或者 UITabBarController
1.控制器的view是UIScrollView\UITableView\UICollectionView時(控制器是UITableViewController的時候)
- (void)viewDidLoad
{
[super viewDidLoad];
// #ifdef __IPHONE_7_0是判斷是否運行在Xcode5環境下,若是在Xcode5環境下才有下面的代碼
#ifdef __IPHONE_7_0
if ([[UIDevice currentDevice].systemVersion floatValue] >= 7.0) {
self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0);
}
#endif
}
2.控制器的view是普通的UIView,非UIScrollView
#ifdef __IPHONE_7_0
- (void)viewDidLayoutSubviews
{
// iOS7 && 沒有包裝導航控制器
if ([[UIDevice currentDevice].systemVersion floatValue] >= 7.0 && self.navigationController == nil) {
CGFloat top = [self.topLayoutGuide length];
// 是否能滾動
if ([self.view isKindOfClass:[UIScrollView class]]) {
UIScrollView *scroll = (UIScrollView *)self.view;
scroll.contentInset = UIEdgeInsetsMake(top, scroll.contentInset.left, scroll.contentInset.bottom, scroll.contentInset.right);
} else {
CGRect bounds = self.view.bounds;
bounds.origin.y = - top;
self.view.bounds = bounds;
}
}
}
#endif
2、包裝有導航控制器的狀況
1> 控制器的view不是UIScrollView
#ifdef __IPHONE_7_0
if ([[UIDevice currentDevice].systemVersion floatValue] >= 7.0) {
self.edgesForExtendedLayout = UIRectEdgeNone;
}
#endif
2> 控制器的view是UIScrollView
不須要寫額外的代碼適配
3、其餘狀況(上述狀況不用死機,只要掌握如下幾點規律)
1.想讓view的內容往下挪動
1> UIView設置bounds的y值
2> UIScrollView設置contentInset的top值
2.防止子控制器的view被導航欄或者tabbar遮住
self.edgesForExtendedLayout = UIRectEdgeNone;
4、多控制器嵌套處理
1.當多重控制器嵌套的時候,最合理的方案是:UITabBarController內部嵌套UINavigationController
2.當UITableViewController的直接父控制器是UINavigationController時,不須要編寫任何適配代碼
3.其餘非UITableViewController須要加上適配代碼
#ifdef __IPHONE_7_0
if ([[UIDevice currentDevice].systemVersion floatValue] >= 7.0) {
self.edgesForExtendedLayout = UIRectEdgeNone;
}
#endif