屏幕适配—约束的添加

我们知道,现在已经不像以前那样只有一个尺寸,现在最少的iPhone开发需要最少需要适配三个以上尺寸。因此以前我们可以使用硬坐标去设定各个控件的位置,但是现在的话已经不可以了,我们需要去做适配,也许你说可以使用两套UI或两套以上的UI,但那样不高效也不符合设计。iOS有两大自动布局利器:autoresizing和autolayout(autolayout是IOS6以后新增)。autoresizing是UIView的属性,一直存在,使用也比较简单,但是没有autolayout那样强大。如果你的界面比较简单,要求的细节没有那么高,那么你完全可以使用autoresizing去进行自动布局。也就意味着,现在,做IOS开发,屏幕适配是必须考虑的问题,而实现屏幕的适配的主要方式就是autolayout,而使用autolayout的关键步骤就是为控件添加相应的约束,

下面,我们就对约束的添加做一些说明。

一:通过系统提供的面板实现约束的添加

现在IOS6以上,系统会自动选择使用autolayout,在“show the file

inspector”面板中可以找到这个属性:

,如果选择了这个属性,那么在编辑区域的右下方就可以看到一些有关autolayout的选项了:

首先,我们对对autolayout主要使用选项做一些说明,其实常用的主要是三个选项:

1.Align面板:

2.Pin面板:

细节说明:constraint to margin:选项的作用。这个属性是IOS8才添加的,它默认会在屏幕左右添加8个点的边距,也就意味着参考不是从屏幕边缘0的位置开始的,而是从8个点的位置开始的。一般来说,对于直接参考屏幕的控件,可以选择这个选项,如果是对于子控件,就没有必要选择了。

3.Resolve面板:

之后,我们介绍一下约束的添加方式。说白了,所谓的约束的本质就是为控件设置好frame属性值,只不过它添加了参照,而不像frame属性一样,只是针对控件本身。所谓参照就是它可以在其它控件或者父容器(如屏幕)有变化的时候,让自身的frame也产生合理的变化。下面以一个简单案例来说明一下约束的添加:

1.案例结果图:

2.添加相应的view控件,选择Pin面板,添加左和上的约束:

注意,不要选择更新约束,因为,如果约束不能正确的得到控件的frame属性,那么系统将很有可能不能正确的绘制出控件,只有当frame有四个属性(size(width.height),origin:(x,y))都能通过约束正确的计算出来才能更新约束。

3,设置宽高,我们需要view的宽度和高度都是屏幕的一半,但是,通过宽高属性却不能进行设置,否则就是固定宽高数值,以后不能进行屏幕的自动适配了。这个时候,面板就不够用,我们还需要使用到约束的修改属性面板,具体实现如下:

3.1先为view添加与屏幕右和下边距为0--view会填充整个屏幕

3.2找到约束,选择想修改的约束,我们想修改view与屏幕右和下的约束关系,那就一个一个选择这些约束进行修改,例如我们先选择右边距约束:

然后,查看约束的具体的属性:

那么一切都一目了然了。根据里面的序号读一遍就可以得到约束这个结果:红色view的最右边等于父容器的最右边数值乘以1加上0,很明显,就是红色view的最右边与父容器的最右边对齐,也就是等宽。所以根据示例结果,只需要将Multiplier修改为0.5,红色view的宽度就是父容器宽度的一半了,对于高度也是同样的处理方式。

说到这里,就不得不说一下在sb中还有一种方面的添加约束的方式:拖线。还是上面那个案例,刚才我们是通过添加四个方向的边距约束(特别是右,下)达到红色view的宽高和高度为父容器的一半,我们也可以通过直接设置红色view的宽高和父容器的宽高之间的关系来达到同样的效果。

1.拖线:

2.这里需要说明的是,拖线的方向决定了显示出的菜单项,如果往左下方向拖线,那么就可以看到添加当前控件与父容器左边距和底边距的选项。其它方向的拖线一样的道理。这里我们选择等宽等高(按住shift键可以同时添加多个约束):

添加后的约束列表:

3.修改添加了等宽等高约束:

读出来就是这样的:blueView的宽度等于父容器的宽度乘以0.5加上0,也就是宽度为父容器宽度一半。

其它几个view的制作方式基本一样啦。

二:通过代码实现约束的添加

代码添加约束其实就是将约束的属性面板所表达的含义使用代码进行描述,官方文档中,它的基本公式为:

意思是:第一个item的属性=(所参照的item的属性*倍数)+常量值。

1.添加约束的类: NSLayoutConstraint

2.添加约束的常用方法:

[NSLayoutConstraint

constraintWithItem:<#(第一个item)#> attribute:<#(某个属性)#> relatedBy:<#(属性与属性之间的关系)#> toItem:<#(参照的item)#> attribute:<#(被参照item的指定属性)#> multiplier:<#(倍数)#> constant:<#(增加的常量)#>];

3.参数的一些说明:

3.1.NSLayoutRelation:这是一个枚举,说明了属性之间的关系,需要注意的是,如果关系设置为等于,但是后期因为某些原因造成属性值不再是等于,则系统会给出相应的警告。

NSLayoutRelationLessThanOrEqual = -1,---小于等于

NSLayoutRelationEqual = 0,---等于

NSLayoutRelationGreaterThanOrEqual = 1, --大于等于

3.2. NSLayoutAttribute:item的属性:

NSLayoutAttributeLeft = 1,左

NSLayoutAttributeRight,右

NSLayoutAttributeTop,顶

NSLayoutAttributeBottom,底

NSLayoutAttributeLeading,左

NSLayoutAttributeTrailing,右

NSLayoutAttributeWidth,宽

NSLayoutAttributeHeight,高

NSLayoutAttributeCenterX,水平中心

NSLayoutAttributeCenterY,垂直中心

NSLayoutAttributeBaseline,基线

NSLayoutAttributeLastBaseline = NSLayoutAttributeBaseline,相当于,两者等价

------------下面是ios8之后的如果想添加默认边距的属性列表--------------

NSLayoutAttributeFirstBaseline NS_ENUM_AVAILABLE_IOS(8_0),

NSLayoutAttributeLeftMargin NS_ENUM_AVAILABLE_IOS(8_0),

NSLayoutAttributeRightMargin NS_ENUM_AVAILABLE_IOS(8_0),

NSLayoutAttributeTopMarginNS_ENUM_AVAILABLE_IOS(8_0),

NSLayoutAttributeBottomMargin NS_ENUM_AVAILABLE_IOS(8_0),

NSLayoutAttributeLeadingMargin NS_ENUM_AVAILABLE_IOS(8_0),

NSLayoutAttributeTrailingMargin NS_ENUM_AVAILABLE_IOS(8_0),

NSLayoutAttributeCenterXWithinMarginsNS_ENUM_AVAILABLE_IOS(8_0),

NSLayoutAttributeCenterYWithinMargins NS_ENUM_AVAILABLE_IOS(8_0),

NSLayoutAttributeNotAnAttribute = 0这不是一个属性,如果一个item的约束不需要参照其它的item,那么就使用这个。

说明:NSLayoutAttributeLeft| NSLayoutAttributeLeading,NSLayoutAttributeRight| NSLayoutAttributeTrailing的区别:

NSLayoutAttributeLeft和NSLayoutAttributeRight代表从左到右进行布局,NSLayoutAttributeLeading和NSLayoutAttributeTrailing代表从前到后进行布局,在我国NSLayoutAttributeLeft和NSLayoutAttributeLeading是一个效果的,布局习惯从左到右,但在有些国家地区(如中东地区等),布局习惯从右往左。那么NSLayoutAttributeRight反而和NSLayoutAttributeLeading是一个效果了,为了避免这些地区的问题,我们推荐使用:NSLayoutAttributeLeading和NSLayoutAttributeTrailing(比较安全和常用)

4.使用代码实现刚才的案例示例:

4.1一定要去除autoresizing属性

4.2创建约束

4.3根据约束添加规则添加约束到控件或者父容器

4.4代码:

-(void)viewDidLoad {

[superviewDidLoad];

//去除autoresizing属性

self.redView.translatesAutoresizingMaskIntoConstraints=NO;

self.view.translatesAutoresizingMaskIntoConstraints=NO;

//添加顶部约束

NSLayoutConstraint*constraintT=[NSLayoutConstraintconstraintWithItem:self.redViewattribute:NSLayoutAttributeToprelatedBy:NSLayoutRelationEqualtoItem:self.redView.superviewattribute:NSLayoutAttributeTop multiplier:1constant:0];

//添加左边约束

NSLayoutConstraint*constraintL=[NSLayoutConstraintconstraintWithItem:self.redViewattribute:NSLayoutAttributeLeftrelatedBy:NSLayoutRelationEqualtoItem:self.redView.superviewattribute:NSLayoutAttributeLeft multiplier:1constant:0];

//添加宽度约束

NSLayoutConstraint*constraintW=[NSLayoutConstraintconstraintWithItem:self.redViewattribute:NSLayoutAttributeWidthrelatedBy:NSLayoutRelationEqualtoItem:self.redView.superviewattribute:NSLayoutAttributeWidth multiplier:0.5constant:0];

////添加高度约束

NSLayoutConstraint*constraintH=[NSLayoutConstraintconstraintWithItem:self.redViewattribute:NSLayoutAttributeHeightrelatedBy:NSLayoutRelationEqualtoItem:self.redView.superviewattribute:NSLayoutAttributeHeight multiplier:0.5constant:0];

//添加约束到控件--根据规则,添加到父容器

[self.redView.superview addConstraints:@[constraintT,constraintL,constraintW,constraintH]];

}

苹果还提供一种添加约束的VFL语言,有兴趣的也可以去看一下相关的文档说明。

当然,以后在进行开发过程中,效率至上,一般会使用第三个框架。如常用的框架有Masonry,一般第三方框架找到框架的帮助文档就能方便的学习和使用了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容