編者注:根據網友們的評論,文章中的方法有很大的局限性,請謹慎使用!
現在由於蘋果公司出了6和6Plus,讓寫蘋果程序的哥們為了做兼容很頭疼。用StoryBoard固然方便,但是後期做兼容要花費太多的時間和精力。
使用AutoLayout雖然會在不同尺寸的屏幕下自動布局,但是很多東西還是要自己手動修改,而且使用AutoLayout的話有一個弊病,就是無法通過代碼來修改StoryBoard上控件的尺寸和位置。
使用純代碼搭建界面又會覺得不夠直觀,要花時間調整布局,雖然方便後期做調整兼容性,但是影響開發效率。
當然個人覺得還是代碼和StoryBoard結合的方式比較方便。
先說下使用本方法的要求,首先iPhone5的界面一定要完全兼容,這樣才能完美兼容6和6Plus。
首先,我麼我們要觀察一下5,6和6Plus的尺寸比例關系。發現了他們的關系後待會做兼容就明白了。

很明顯能看出這三種屏幕的尺寸寬高比是差不多的,因此可以在5的基礎上,按比例放大來兼容6和6Plus的屏幕。
在AppDelegate.h中
@property float autoSizeScaleX; @property float autoSizeScaleY;
在AppDelegate.m中
#define ScreenHeight [[UIScreen mainScreen] bounds].size.height//獲取屏幕高度,兼容性測試
#define ScreenWidth [[UIScreen mainScreen] bounds].size.width//獲取屏幕寬度,兼容性測試
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
AppDelegate *myDelegate = [[UIApplication sharedApplication] delegate];
if(ScreenHeight > 480){
myDelegate.autoSizeScaleX = ScreenWidth/320;
myDelegate.autoSizeScaleY = ScreenHeight/568;
}else{
myDelegate.autoSizeScaleX = 1.0;
myDelegate.autoSizeScaleY = 1.0;
}
}因為iPhone4s屏幕的高度是480,因此當屏幕尺寸大於iPhone4時,autoSizeScaleX和autoSizeScaleY即為當前屏幕和iPhone5尺寸的寬高比。比如,
如果是5,autoSizeScaleX=1,autoSizeScaleY=1;
如果是6,autoSizeScaleX=1.171875,autoSizeScaleY=1.17429577;
如果是6Plus,autoSizeScaleX=1.29375,autoSizeScaleY=1.2957;
現在我們獲取了比例關系後,先來看一下如何解決代碼設置界面時的兼容。
CGRectMake(CGFloat x, CGFloat y, CGFloat width, CGFloat height)這個方法使我們常用的設置尺寸的方法,現在我設置了一個類似於這樣的方法。
在.m文件中
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake1(100, 100, 50, 50)];
CG_INLINE CGRect//注意:這裡的代碼要放在.m文件最下面的位置
CGRectMake1(CGFloat x, CGFloat y, CGFloat width, CGFloat height)
{
AppDelegate *myDelegate = [[UIApplication sharedApplication] delegate];
CGRect rect;
rect.origin.x = x * myDelegate.autoSizeScaleX; rect.origin.y = y * myDelegate.autoSizeScaleY;
rect.size.width = width * myDelegate.autoSizeScaleX; rect.size.height = height * myDelegate.autoSizeScaleY;
return rect;
}這樣,這個btn按鈕在5,6和6Plus的位置和尺寸比例都是一樣的。
代碼兼容完之後,來看一下StoryBoard的兼容,當然,在平時的項目中我們不可能就一兩個視圖,而且每個視圖裡面可定還套有很多其他視圖,如果把所有視圖的尺寸用手動輸入CGRectMake的方法來改兼容的話工作量非常大,而且容易出錯。經過多次試驗,我想出一種能快速兼容大多數界面的方法
在AppDelegate.m中
//storyBoard view自動適配
+ (void)storyBoradAutoLay:(UIView *)allView
{
for (UIView *temp in allView.subviews) {
temp.frame = CGRectMake1(temp.frame.origin.x, temp.frame.origin.y, temp.frame.size.width, temp.frame.size.height);
for (UIView *temp1 in temp.subviews) {
temp1.frame = CGRectMake1(temp1.frame.origin.x, temp1.frame.origin.y, temp1.frame.size.width, temp1.frame.size.height);
}
}
}
//修改CGRectMake
CG_INLINE CGRect
CGRectMake1(CGFloat x, CGFloat y, CGFloat width, CGFloat height)
{
AppDelegate *myDelegate = [[UIApplication sharedApplication] delegate];
CGRect rect;
rect.origin.x = x * myDelegate.autoSizeScaleX; rect.origin.y = y * myDelegate.autoSizeScaleY;
rect.size.width = width * myDelegate.autoSizeScaleX; rect.size.height = height * myDelegate.autoSizeScaleY;
return rect;
}storyBoradAutoLay是把當前view進行兩層遍歷,把裡面的UIView類型的控件的尺寸取出來,乘以對應的比例再賦值給它的尺寸,這樣StoryBoard裡的兼容就完成了。如果你的界面裡嵌套的比較多的話可以多加幾層遍歷。
在繼承了UIViewController的.m文件中
#import "AppDelegate.h"
- (void)viewDidLoad{
[super viewDidLoad];
[AppDelegate storyBoradAutoLay:self.view];
}在所有的繼承了UIViewController的文件中,都加上storyBoradAutoLay這句代碼,就能把當前的view進行兼容。
現在我們來看一下使用了該方法兼容的前後對比效果吧。
iPhone6兼容前

iPhone6兼容後

iPhone6Plus兼容前

iPhone6Plus兼容後

如果整個項目做完後才開始做兼容的話這個方法的優勢就體現出來了,面對幾十個工程文件,只需自定義並且替換你的CGRectMake方法,再加上storyBoradAutoLay這個方法就瞬間完成大部分甚至全部的兼容。
其實還是比較建議用代碼和StoryBoard結合的方式來寫代碼,無論是從做兼容還是效率來說都是比較好的。
如果遇到tableView的或者其他的兼容改動,手動調整一下即可。
(本文作者:Bear)