屏幕適配問題共有四種解決方案:(1)根據屏幕寬高寫控件frame(下策);(2)Autoresizing的使用(中策);(3)AutoLayout的使用(上策);(4)sizeClasses+AutoLayout的使用(上上策)。下面將會分別來進行敘述。ios
(1)根據屏幕寬高寫控件frame
利用寬高比,在不一樣的屏幕中來進行對控件的位置與控件的寬高進行等比例縮放.選定一個型號的屏幕的寬高爲基準,進行等比例縮放.例如以iPhone6或者iPhone6s爲基準.git
其寬高分別是375與667.Iphone6ScaleWidth = [UIScreen mainScreen].bounds.size.width/375; Iphone6ScaleHeight = [UIScreen mainScreen].bounds.size.height/667;github
若是是iPhone6或者iPhone6s則Iphone6ScaleWidth與Iphone6ScaleHeight的值都爲1.可是此方法對於iPhone5以後的型號能夠適用.由於咱們知道iPhone4或者iPhone4s尺寸是320x480.iPhone5是320x568.因此對於4或者4s來講計算獲得的寬高比不相同.可能會形成一個方形控件,在iPhone5以後的機型上顯示的都是正方形.可是在4或者4s上顯示的是長方形.須要進行本身的判斷(目前來講4或者4s市場上已經很少見了).app
同時也能夠在代理增長兩個屬性,寬高比例屬性,例如:框架
1 @interface AppDelegate : UIResponder <UIApplicationDelegate> 2 @property float autoSizeScaleX; 3 @property float autoSizeScaleY; 4 5 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 6 if(CurrentScreenHeight > 480){ 7 nowAppDelegate().autoSizeScaleX = CurrentScreenWidth/320.0; 8 nowAppDelegate().autoSizeScaleY = CurrentScreenHeight/568.0; 9 }else{ 10 nowAppDelegate().autoSizeScaleX = 1.0;其中nowAppDelegate() = (AppDelegate *)[[UIApplication sharedApplication] delegate]; 11 nowAppDelegate().autoSizeScaleY = 1.0; 12 } 13 14 }
在項目對於控件的位置和尺寸乘以這兩個縮放比例.less
(2)Autoresizing的使用工具
在Autolayout之前,有Autoresizing能夠作屏幕適配,但侷限性較大,只能針對父子關係進行有限調整,如邊距固定,尺寸可變,對於兄弟關係的調整沒法實現。對於UI比較固定的app,這種方式基本知足。相比之下,Autolayout比Autoresizing強大不少。佈局
(3)AutoLayout的使用spa
在之前的iOS程序是怎樣佈局UI的?代理
常常編寫大量的座標計算代碼;
爲了保證在各類屏幕上都能有完美的UI界面效果,有時還須要分別爲幾種屏幕編寫不一樣的座標計算代碼(即傳說中的「屏幕適配」)
什麼是Autolayout?
Autolayout是一種「自動佈局」技術,專門用來佈局UI界面的。
Autolayout自iOS6開始引入,因爲Xcode4的不給力,當時並無獲得很大的推廣。
自iOS7(Xcode5)開始,Autolayout的開發效率獲得很大的提高。
蘋果官方也推薦開發者使用Autolayout來佈局UI界面。
Autolayout可以很輕鬆的解決屏幕適配的問題。
代碼以下:
1 UIView *headView = [[UIView alloc] init]; 2 headView.translatesAutoresizingMaskIntoConstraints = NO; 3 [self.view addSubview:headView]; 4 headView.backgroundColor = [UIColor redColor]; 5 NSLayoutConstraint *headViewLeft = [NSLayoutConstraint constraintWithItem:headView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0]; 6 NSLayoutConstraint *headViewTop = [NSLayoutConstraint constraintWithItem:headView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:0]; 7 NSLayoutConstraint *headViewRight = [NSLayoutConstraint constraintWithItem:headView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant:0]; 8 NSLayoutConstraint *headViewHeight = [NSLayoutConstraint constraintWithItem:headView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:0 constant:200]; 9 self.headHeightCons = headViewHeight; 10 [self.view addConstraints:@[headViewTop,headViewLeft,headViewRight]]; 11 [headView addConstraint:headViewHeight]; 12 13 14 UIImage *imageLol = [UIImage imageNamed:@"lol"]; 15 UIImageView *imageViewLol = [[UIImageView alloc] initWithImage:imageLol]; 16 [headView addSubview:imageViewLol]; 17 imageViewLol.translatesAutoresizingMaskIntoConstraints = NO; 18 [imageViewLol setContentMode:UIViewContentModeScaleAspectFill]; 19 20 21 NSLayoutConstraint *imageLolViewLeft = [NSLayoutConstraint constraintWithItem:imageViewLol attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:headView attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0]; 22 NSLayoutConstraint *imageViewLolViewTop = [NSLayoutConstraint constraintWithItem:imageViewLol attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:headView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0]; 23 NSLayoutConstraint *imageViewLolViewRight = [NSLayoutConstraint constraintWithItem:imageViewLol attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:headView attribute:NSLayoutAttributeRight multiplier:1.0 constant:0]; 24 NSLayoutConstraint *imageViewLolViewBottom = [NSLayoutConstraint constraintWithItem:imageViewLol attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:headView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0]; 25 [headView addConstraints:@[imageLolViewLeft,imageViewLolViewTop,imageViewLolViewRight,imageViewLolViewBottom]];
(4)sizeClasses+AutoLayout的使用
iOS8中新增了Size Classes特性,他是對當前全部iOS設備尺寸的一個抽象。
用法:
屏幕的寬和高分別分紅三種狀況:(Compact,Regular,Any).也就是緊湊,正常和任意。這樣寬和高三三整合,一共九種狀況。針對每一種狀況,若是須要的話,咱們能夠單獨在storyboard或xib中設置UIView的自動佈局約束,甚至某一個button是否顯示都是能輕鬆實現的。
固然,還有一種就是使用Masonry框架進行屏幕適配
Masonry是一個輕量級的佈局框架,擁有本身的描述語法,採用更優雅的鏈式語法封裝自動佈局,簡潔明瞭並具備高可讀性,並且同時支持 iOS 和 Max OS X。Masonry是一個用代碼寫iOS或OS界面的庫,能夠代替Auto layout。Masonry的github地址:https://github.com/SnapKit/Masonry
Masonry配置
- 推薦使用pods方式引入類庫,pod 'Masonry',若不知道pod如何使用,狀況個人另外一篇文章: 提升ios開發效率的工具
- 引入頭文件 #import "Masonry.h"
Masonry使用講解
mas_makeConstraints 是給view添加約束,約束有幾種,分別是邊距,寬,高,左上右下距離,基準線。添加過約束後能夠有修正,修正有offset(位移)修正和multipliedBy(倍率)修正。
語法通常是 make.equalTo or make.greaterThanOrEqualTo or make.lessThanOrEqualTo + 倍數和位移修正。
注意點1: 使用 mas_makeConstraints方法的元素必須事先添加到父元素的中,例如[self.view addSubview:view];
注意點2: masequalTo 和 equalTo 區別:masequalTo 比equalTo多了類型轉換操做,通常來講,大多數時候兩個方法都是 通用的,可是對於數值元素使用mas_equalTo。對於對象或是多個屬性的處理,使用equalTo。特別是多個屬性時,必須使用equalTo,例如 make.left.and.right.equalTo(self.view);
注意點3: 注意到方法with和and,這連個方法其實沒有作任何操做,方法只是返回對象自己,這這個方法的左右徹底是爲了方法寫的時候的可讀性 。make.left.and.right.equalTo(self.view);和make.left.right.equalTo(self.view);是徹底同樣的,可是明顯的加了and方法的語句可讀性 更好點。
Masonry初級使用例子
1 // exp1: 中心點與self.view相同,寬度爲400*400 2 -(void)exp1{ 3 UIView *view = [UIView new]; 4 [view setBackgroundColor:[UIColor redColor]]; 5 [self.view addSubview:view]; 6 [view mas_makeConstraints:^(MASConstraintMaker *make) { 7 make.center.equalTo(self.view); 8 make.size.mas_equalTo(CGSizeMake(400,400)); 9 }]; 10 } 11 //exp2: 上下左右邊距都爲10 12 -(void)exp2{ 13 UIView *view = [UIView new]; 14 [view setBackgroundColor:[UIColor redColor]]; 15 [self.view addSubview:view]; 16 [view mas_makeConstraints:^(MASConstraintMaker *make) { 17 make.edges.equalTo(self.view).with.insets(UIEdgeInsetsMake(10, 10, 10, 10)); 18 // make.left.equalTo(self.view).with.offset(10); 19 // make.right.equalTo(self.view).with.offset(-10); 20 // make.top.equalTo(self.view).with.offset(10); 21 // make.bottom.equalTo(self.view).with.offset(-10); 22 }]; 23 } 24 //exp3 讓兩個高度爲150的view垂直居中且等寬且等間隔排列 間隔爲10 25 -(void)exp3{ 26 UIView *view1 = [UIView new]; 27 [view1 setBackgroundColor:[UIColor redColor]]; 28 [self.view addSubview:view1]; 29 UIView *view2 = [UIView new]; 30 [view2 setBackgroundColor:[UIColor redColor]]; 31 [self.view addSubview:view2]; 32 [view1 mas_makeConstraints:^(MASConstraintMaker *make) { 33 make.centerY.mas_equalTo(self.view.mas_centerY); 34 make.height.mas_equalTo(150); 35 make.width.mas_equalTo(view2.mas_width); 36 make.left.mas_equalTo(self.view.mas_left).with.offset(10); 37 make.right.mas_equalTo(view2.mas_left).offset(-10); 38 }]; 39 [view2 mas_makeConstraints:^(MASConstraintMaker *make) { 40 make.centerY.mas_equalTo(self.view.mas_centerY); 41 make.height.mas_equalTo(150); 42 make.width.mas_equalTo(view1.mas_width); 43 make.left.mas_equalTo(view1.mas_right).with.offset(10); 44 make.right.equalTo(self.view.mas_right).offset(-10); 45 }]; 46 }
Masonry高級使用例子1
iOS計算器使用Masorny佈局:
1 //高級佈局練習 ios自帶計算器佈局 2 -(void)exp4{ 3 //申明區域,displayView是顯示區域,keyboardView是鍵盤區域 4 UIView *displayView = [UIView new]; 5 [displayView setBackgroundColor:[UIColor blackColor]]; 6 [self.view addSubview:displayView]; 7 UIView *keyboardView = [UIView new]; 8 [self.view addSubview:keyboardView]; 9 //先按1:3分割 displView(顯示結果區域)和 keyboardView(鍵盤區域) 10 [displayView mas_makeConstraints:^(MASConstraintMaker *make) { 11 make.top.equalTo(self.view.mas_top); 12 make.left.and.right.equalTo(self.view); 13 make.height.equalTo(keyboardView).multipliedBy(0.3f); 14 }]; 15 [keyboardView mas_makeConstraints:^(MASConstraintMaker *make) { 16 make.top.equalTo(displayView.mas_bottom); 17 make.bottom.equalTo(self.view.mas_bottom); 18 make.left.and.right.equalTo(self.view); 19 }]; 20 //設置顯示位置的數字爲0 21 UILabel *displayNum = [[UILabel alloc]init]; 22 [displayView addSubview:displayNum]; 23 displayNum.text = @"0"; 24 displayNum.font = [UIFont fontWithName:@"HeiTi SC" size:70]; 25 displayNum.textColor = [UIColor whiteColor]; 26 displayNum.textAlignment = NSTextAlignmentRight; 27 [displayNum mas_makeConstraints:^(MASConstraintMaker *make) { 28 make.left.and.right.equalTo(displayView).with.offset(-10); 29 make.bottom.equalTo(displayView).with.offset(-10); 30 }]; 31 //定義鍵盤鍵名稱,?號表明合併的單元格 32 NSArray *keys = @[@"AC",@"+/-",@"%",@"÷" 33 ,@"7",@"8",@"9",@"x" 34 ,@"4",@"5",@"6",@"-" 35 ,@"1",@"2",@"3",@"+" 36 ,@"0",@"?",@".",@"="]; 37 int indexOfKeys = 0; 38 for (NSString *key in keys){ 39 //循環全部鍵 40 indexOfKeys++; 41 int rowNum = indexOfKeys %4 ==0? indexOfKeys/4:indexOfKeys/4 +1; 42 int colNum = indexOfKeys %4 ==0? 4 :indexOfKeys %4; 43 NSLog(@"index is:%d and row:%d,col:%d",indexOfKeys,rowNum,colNum); 44 //鍵樣式 45 UIButton *keyView = [UIButton buttonWithType:UIButtonTypeCustom]; 46 [keyboardView addSubview:keyView]; 47 [keyView setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 48 [keyView setTitle:key forState:UIControlStateNormal]; 49 [keyView.layer setBorderWidth:1]; 50 [keyView.layer setBorderColor:[[UIColor blackColor]CGColor]]; 51 [keyView.titleLabel setFont:[UIFont fontWithName:@"Arial-BoldItalicMT" size:30]]; 52 //鍵約束 53 [keyView mas_makeConstraints:^(MASConstraintMaker *make) { 54 //處理 0 合併單元格 55 if([key isEqualToString:@"0"] || [key isEqualToString:@"?"] ){ 56 if([key isEqualToString:@"0"]){ 57 [keyView mas_makeConstraints:^(MASConstraintMaker *make) { 58 make.height.equalTo(keyboardView.mas_height).with.multipliedBy(.2f); 59 make.width.equalTo(keyboardView.mas_width).multipliedBy(.5); 60 make.left.equalTo(keyboardView.mas_left); 61 make.baseline.equalTo(keyboardView.mas_baseline).with.multipliedBy(.9f); 62 }]; 63 }if([key isEqualToString:@"?"]){ 64 [keyView removeFromSuperview]; 65 } 66 } 67 //正常的單元格 68 else{ 69 make.width.equalTo(keyboardView.mas_width).with.multipliedBy(.25f); 70 make.height.equalTo(keyboardView.mas_height).with.multipliedBy(.2f); 71 //按照行和列添加約束,這裏添加行約束 72 switch (rowNum) { 73 case 1: 74 { 75 make.baseline.equalTo(keyboardView.mas_baseline).with.multipliedBy(.1f); 76 keyView.backgroundColor = [UIColor colorWithRed:205 green:205 blue:205 alpha:1]; 77 } 78 break; 79 case 2: 80 { 81 make.baseline.equalTo(keyboardView.mas_baseline).with.multipliedBy(.3f); 82 } 83 break; 84 case 3: 85 { 86 make.baseline.equalTo(keyboardView.mas_baseline).with.multipliedBy(.5f); 87 } 88 break; 89 case 4: 90 { 91 make.baseline.equalTo(keyboardView.mas_baseline).with.multipliedBy(.7f); 92 } 93 break; 94 case 5: 95 { 96 make.baseline.equalTo(keyboardView.mas_baseline).with.multipliedBy(.9f); 97 } 98 break; 99 default: 100 break; 101 } 102 //按照行和列添加約束,這裏添加列約束 103 switch (colNum) { 104 case 1: 105 { 106 make.left.equalTo(keyboardView.mas_left); 107 } 108 break; 109 case 2: 110 { 111 make.right.equalTo(keyboardView.mas_centerX); 112 } 113 break; 114 case 3: 115 { 116 make.left.equalTo(keyboardView.mas_centerX); 117 } 118 break; 119 case 4: 120 { 121 make.right.equalTo(keyboardView.mas_right); 122 [keyView setBackgroundColor:[UIColor colorWithRed:243 green:127 blue:38 alpha:1]]; 123 } 124 break; 125 default: 126 break; 127 } 128 } 129 }]; 130 } 131 }
本例子使用的baseline去控制高度位置,這彷佛不是太準,若是想要精準控制高度位置,可使用一行一行添加的方法,每次當前行的top去equelTo上一行的bottom。 給個提示:
for(遍歷全部行) for(遍歷因此列) //當前行約束根據上一行去設置 ......