iOS屏幕适配(纯代码)

  在iOS实际项目开发中, 我们经常要适配不同尺寸的屏幕,如iPhone4s,iPhone5/s,iPhone6/s,iPhone6Plus等.  在代码中创建一个控件如:
UILabel *label = [UILabel alloc] init];
label.frame = CGRectMake(CGFloat x, CGFloat y, CGFloat width, CGFloat height);
[self.view addSubView : label];
  我相信很多童鞋都是这么写的. 这样写也没有错. 但是当控件一多,设置控件的frame就成了一个难题. 有时候我们只能去估算控件的大小以及相对位置. 这样就有一个不好之处: 当你在一个设备上(如iPhone5s) 调整好了布局,那么当你运行在iPhone4s, 或者iPhone6s或者iPhone6s+ 上面的时候,你会发现原本已经布局好的界面变形了. 这就是由于屏幕尺寸的不同导致的问题.那我们该如何解决这个问题呢?  下面我将娓娓道来: 
  第一种方式也是我们经常使用的Autolayout(自动布局), 值得注意的是,Autolayout只适用 xib 跟 storyBoard.  Autolayout是一种“自动布局”技术,专门用来布局UI界面的.Autolayout自iOS6开始引入,由于Xcode4的不给力,当时并没有得到很大的推广.自iOS7(Xcode5)开始,Autolayout的开发效率得到很大的提升.苹果官方也推荐开发者使用Autolayout来布局UI界面.Autolayout能够很轻松的解决屏幕适配的问题.  它是通过在xib或者storyBoard中设置控件的依赖关系,从而适配.
  提到Autolayout,不得不提Autoresizing.在Autolayout以前,有Autoresizing可以做屏幕适配,但局限性较大,只能针对父子关系进行有限调整,如边距固定,尺寸可变,对于兄弟关系的调整无法实现.对于UI比较固定的app,这种方式基本满足.相比之下,Autolayout比Autoresizing强大很多.
  还有一个就是Size Classes.  Size Classes是iOS8中新增了特性,他是对当前所有iOS设备尺寸的一个抽象.  屏幕的宽和高分别分成三种情况:(Compact,Regular,Any).也就是紧凑,正常和任意. 这样宽和高三三整合,一共九种情况. 针对每一种情况,如果需要的话,我们可以单独在storyboard或xib中设置UIView的自动布局约束,甚至某一个button是否显示都是能轻松实现的. 具体使用方法这里就不做详细说明. 
  下面所要说的就是今天的重点: 纯代码实现屏幕适配. 在开始说之前,先让我们了解一下iPhone的机型和尺寸的对应关系:
Snip20160520_1.png

很明显能看出这三种屏幕的尺寸宽高比是差不多的,因此可以在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){ // 这里以(iPhone4S)为准
        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文件中

CG_INLINE CGRect
TS_CGRectMake(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;
}

当我们使用的时候直接这样做
UIImageView *imageview = [[UIImageView alloc] initWithFrame:TS_CGRectMake(100, 100, 50, 50)];
这样我们得出的就是转换后的坐标了. 这样,这个imageview在5,6和6Plus的位置和尺寸比例都是一样的. 妈妈再也不用担心屏幕的适配了.
  如果整个项目做完后才开始做适配的话这个方法的优势就体现出来了,面对几十个工程文件,只需自定义并且替换你的CGRectMake方法,再加上storyBoradAutoLay这个方法就瞬间完成大部分甚至全部的适配,如果遇到tableView的或者其他的手动调整一下即可. 
  当然这个我已经准备设计一个类, 写好了我会第一时间放在我的gitHub上,方便大家的使用.
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,319评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,801评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,567评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,156评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,019评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,090评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,500评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,192评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,474评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,566评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,338评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,212评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,572评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,890评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,169评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,478评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,661评论 2 335

推荐阅读更多精彩内容

  • 屏幕适配 本章节主要还是说明如何让应用程序能够适配在苹果不同的屏幕和如何让应用中的内容在不同的屏幕下能够正常的放置...
    AlanGe阅读 688评论 0 2
  • 1.尺寸适配1.原因 iOS7中所有导航栏都为半透明,导航栏(height=44)和状态栏(height=20)不...
    LZM轮回阅读 6,073评论 1 4
  • 前言 iPhone自诞生以来,随着其屏幕尺寸不断的多样化,屏幕适配的技术一直在发展更新。目前,iOS系统版本已经更...
    VV木公子阅读 15,324评论 24 170
  • Autoresizing 在Autolayout之前,有Autoresizing可以作屏幕适配,但局限性较大,有些...
    YANGGQ阅读 234评论 0 0
  • iPhone4s之前,屏幕都是3.5inch,所以当时没有屏幕适配概念,开发人员全部用frame、bounds、c...
    CoderDaveChen阅读 599评论 0 0