Xib创建视图子视图尺寸难点

如果是底部的view下移后就会造成bug,有些view会下移,那么你完全可以使用autoresizing去进行自动布局,其中重点是autolayout的使用,按比例跟随父控件变化的宽度,这六种枚举值的意思如下,但是有时也会有问题

图片 5

新近超过了如此三个bug,开采当状态栏退换(比如现身开启火爆,另贰个程序后台获取地点等)后,某些view会下移,而略带view不会下移,如若是底层的view下移后就能够促成bug。于是作者就追究了一下并做出总结。

显示屏适配

本章节首要依旧印证什么让应用程序能够适配在苹果差异的显示屏和什么让动用中的内容在差异的荧屏下能够符合规律的停放。
实际表明了:

  1. 显示器适配的前行
  2. autoresizing的使用
  3. autolayout的使用
  4. 代码达成autolayout
  5. sizeClass的使用。

在后天的剧情之上现在利用大批量的实例来验证区别情况下的适配情势。其中主固然autolayout的选用

  • 显示屏适配的腾飞
  • autoresizing的使用
  • autolayout的使用
  • sizeClass的使用

显示屏适配跑不脱以下二种方法,那就一一道来:

选拔Xib成立视图能够非常快捷的造成,不过一时也有毛病。

当状态栏出现后,当前视图的根view的frame会爆发更换,它的y值会扩张20,高度会削减20。而[UIScreen mainScreen].bounds[UIApplication sharedApplication].keyWindow.bounds那四个措施获得的frame是不会变动的。所以一不注意就很轻便写出情形栏改成后会引起视图下移的bug。

叩问显示屏适配的发展史

序言:今后曾经不像以前那么只有四个尺寸,未来至少的BlackBerry开拓供给至少供给适配八个尺码。因而从前小编们能够动用硬坐标去设定各类控件的岗位,但是今后的话已经不得以了,我们需求去做适配,恐怕你说能够应用两套UI或两套以上的UI,但那样不便捷也不符合设计。iOS有两大机关布局利器:autoresizing

autolayout(autolayout是IOS6后头新扩张)。autoresizing是UIView的习性,向来留存,使用也比较轻易,可是尚未autolayout那样庞大。借令你的分界面前蒙受比简单,需求的内部原因尚未那么高,那么您完全能够使用autoresizing去实行机动布局

iphone3/iphone 3GS:未有荧屏适配,直接使用frame固定子控件的大大小小
iphone4
/4s/ipad:iphone显示器尺寸一样,可是只要进展ipad开辟,就要求考虑显示器适配
iphone
5/5c/5s:显示屏尺寸不平等,须求挂念荧屏适配(使用autoresizing/autolayout实现)

Autoresizing;

问题

在开首化Xib视图时给视图的frame赋值,开采并从未改变视图的大小,你或许会疑惑,是否绝非加约束?

标题不是出在加约束方面,而是约束加错了,那一个荒唐是在创登时系统就早就加好了。

封锁分二种,autolayout和autoresizing,大家一般会采用autolayout来约束控件,然而,固然加上autolayout,难点或然会冒出。
难题出在了autoresizing上,先看下图

图片 1

image.png

此时翻开视图的autoresizing是下边这种场地:

图片 2

image.png

然而既然是自定义视图,将要修改视图的尺码,所以上面那天性情的装置是必需的

图片 3

image.png

安装完这性格子,大家再回过来看autoresizing

图片 4

image.png

UIViewAutoresizingFlexibleLeftMargin–自动调度view与父视图左侧距,以管教侧面距不变
UIViewAutoresizingFlexibleWidth–自动调解view的肥瘦,保险侧边距和右侧距不改变
UIViewAutoresizingFlexibleRightMargin–自动调度view与父视图右侧距,以保障侧边距不改变
UIViewAutoresizingFlexibleTopMargin–自动调节view与父视图上边距,以管教上面距不改变
UIViewAutoresizingFlexibleHeight–自动调治view的可观,以担保上面距和底下距不改变
UIViewAutoresizingFlexibleBottomMargin–自动调整view与父视图的下面距,以确定保障上面距不改变
那6个枚举值分别对应图中的6条线,
第二个枚举值对应的是左边的“|-|”
第4个枚举值对应的是中间的“<->”
第2个枚举值对应的是左边的“|-|”
首个枚举值对应的是上面的“|-|”
第5个枚举值对应的是中等边竖着的“<->”
第6个枚举值对应的是上边的“|-|”

当那6条线都丰硕去的时候难点就应际而生了。

  1. view成立的时候已经有状态栏
  2. view创立的时候从不状态栏,view展现完全后才出现状态栏

autoresizing的使用

Autoresizing是Autolayout的鼻祖,当设置UIView的实例对象的autoresizesSubviews属性值为
true,那么其子view会依据自身的autoresizingMask属性值自动调度与superview的岗位和分寸关系,aoturesizingMask有各样可结合的使用值,默许是none,那四种枚举值的意思如下:

缓慢解决方案是

将中等的两条“<->”去掉。

autoresizing 的详解
参考这里

最简便易行的秘诀正是应用autolayout举办约束,並且靠头部的视图必须要从底层举行约束,那样无论第一种情景依旧其次种情景都不会发生bug。恐怕使用autoresizing,即设置view.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;

使用autoresizing的前提
  1. 内需去除autolayout选项,因为那四个特性争辩。view的autoresizesSubviews属性为yes时(默以为yes),autoresizing才会生效

  2. 从XCODE6开始,Storyboard&Xib私下认可是全自动布局,因而我们需求手动调度,能力应用autoresizing

![](https://upload-images.jianshu.io/upload_images/2229471-f44eebab11414dc3.png)

FIexibleLeftMargin:按百分比跟随父控件变化的左间距;

如果在不选拔autolayout和autoresizingMask的情状下

安装面板表达

图片 5

FIexibleWidth:按比例跟随父控件变化的宽窄

  • view成立的时候曾经有状态栏
使用storyboard实现autoresizing
  • 采纳品质面板完毕轻易的案例示例
  • 体验六根线的意思

FIexibleRighMargin:右间距

这种情景就很轻松,当大家写frame获取当前视图大小的时候绝不选用[UIScreen mainScreen].bounds[UIApplication sharedApplication].keyWindow.bounds那七个主意,改为[UIApplication sharedApplication].keyWindow.rootViewController.view.bounds那样来获得,那样获取的结果便是近来有无状态栏的时候的视图尺寸。

动用代码完成autoresizing
  • UIViewAutoresizing是贰个枚举类型,默许是UIViewAutoresizingNone,也正是不做任何管理

typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
    UIViewAutoresizingNone                 = 0,
    UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
    UIViewAutoresizingFlexibleWidth        = 1 << 1,
    UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
    UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
    UIViewAutoresizingFlexibleHeight       = 1 << 4,
    UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};
  • 属性解释:

UIViewAutoresizingNone:不会随父视图的改观而退换
UIViewAutoresizingFlexibleLeftMargin:自动调治view与父视图左边距,以有限辅助侧边距不改变
UIViewAutoresizingFlexibleWidth:自动调治view的增长幅度,保险左边距和侧边距不变
UIViewAutoresizingFlexibleRightMargin:自动调度view与父视图右侧距,以担保左侧距不改变
UIViewAutoresizingFlexibleTopMargin:自动调治view与父视图上边距,以确定保证上边距不改变
UIViewAutoresizingFlexibleHeight:自动调节view的莫斯中国科学技术大学学,以保险上边距和底下距不改变
UIViewAutoresizingFlexibleBottomMargin:自动调解view与父视图的底下距,以保证上面距不改变

证澳优下,借使是常事利用Storyboard/Xib设置autoresizing,那么转换使用代码设置autoresizing的话,轻易并发精通错误问题。譬如说UIViewAutoresizingFlexibleTopMargin,恐怕会被误以为是顶上部分距离不改变,其实是底层距离不变

  • autoresizing组合使用:枚举中的值能够选用|隔断,相同的时候兼有多少个值的职能,可以针对不相同的气象作分裂的变动:如:UIViewAutoresizingFlexibleWidth
    |
    UIViewAutoresizingFlexibleBottomMargin。意思是:view的拉长率依据父视图的拉长率比例进行缩放,距离父视图最上端距离不改变

  • 注意事项:

    • 从XCODE6开首,Storyboard&Xib暗中同意是半自动布局,因而我们须要手动调节,工夫采纳autoresizing
  • 代码示例:

- (void)viewDidLoad {
    [super viewDidLoad];
    //1.添加UIView:以320*480为例
    UIView *testView=[[UIView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height-44, self.view.frame.size.width, 44)];

    //2.设置UIView的属性(背景色,frame)
    testView.backgroundColor=[UIColor redColor];

    //3.添加UIView的autoresizing属性
    //testView.autoresizingMask=UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleTopMargin;
    [testView setAutoresizingMask: UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleTopMargin];

    //4.添加自定义view到界面
    [self.view addSubview:testView];
}
  • autoresizing使用进度中的注意事项

    • 必然要先去除use autolayout选项
    • 在使用autoreszing的时候是以父容器做为参照进行布局的。
  • autoresizing的局限性

    • 它不得不描述老爹和儿子控件之间的布局关系,而不能够描述子控件与子控件之间的布局关系

FIexibleTopMargin:顶间距

  • view成立的时候未有状态栏,view突显完全后才出现状态栏

autolayout的使用

  • 运用场馆:

    • 当今Apple公布的依次产品上市之后,设备的显示器分辨率也会有了不小的变化,Motorola4/4S是3.5寸,HTC5是4.0寸,ipad2/new
      ipad/ipad4是9.7寸的,ipad
      mini是7.0的,分辨率也各不相同,使用守旧frame布局的专门的职业量必将进一步大
    • 可感觉二个ViewController做出多少个例外的尺寸的View来,可是那样会大大的影响到支付的快慢
    • autolayout:一种对差异荧屏尺寸有更加好相配的全自动布局机制
    • 好处:
      1、你基本上能够毫不思虑显示屏分裂分辨率的主题素材,你终于能够不用在viewDidLoad方法里判别分化分辨率下,不一样控件应该献身哪个地方,也许针对区别分辨率写分化的storyboard和xib
      2、你能够放任那贰个依据不相同文字来测算tableViewCell、UILabel中度的代码了,因为autolayout会帮您活动测算好
      3、若是您的布局在横屏竖屏下转移不是特意大,你不用再为横着竖着写两套代码或许写八个storyboard/xib了
    • 进而:当您的页面不会改造全部布局和陈设,只有在分裂显示屏尺寸、分化文字和剧情下有适应性的转变,那这种景况选拔autolayout就再妥贴不过了
  • 设置autolayout的性子面板表达

    • pin面板和align面板:
    ![](https://upload-images.jianshu.io/upload_images/2229471-810ffbe8e2bcd84f.png)

-   resolve面板:



    ![](https://upload-images.jianshu.io/upload_images/2229471-5ca4866f4d3f30de.png)

    Snip20170827\_5.png

-   resizing behevior面板:



    ![](https://upload-images.jianshu.io/upload_images/2229471-123039146b65535b.png)
  • 采用autolayout不再必要设置子控件的frame

    • 透过利用 老爹和儿子控件之间的约束 或者子控件与子控件之间的自律实行frame的安装。
    • 丰硕封锁示例:
    ![](https://upload-images.jianshu.io/upload_images/2229471-6c1e1f61f1a60c9e.png)

    Snip20170827\_6.png
  • 使用autolayout进度中的注意事项:约束远远不足和束缚争执

    • 新民主主义革命:表达必需的多个约束有缺点和失误,增多缺点和失误的牢笼就足以
    • 香艳:表明重新扩展加了约束,能够采取删除在那之中重复的束缚
  • 代码完结autolayout

    • 动用NSLayoutConstraint那么些类为子控件增加约束
    • 增加封锁的晤面语法规律:
      item1.attribute = multiplier ? item2.attribute + constant,
      对应的丰裕约束的不二秘诀:
      [NSLayoutConstraint
      constraintWithItem:<#(需求增添约束的子控件对象)#>
      attribute:<#(为子控件的哪贰天性格加多约束)#>
      relatedBy:<#(如何进展封锁(如超过,等于…))#>
      toItem:<#(参照的控件对象)#>
      attribute:<#(所参照控件的哪壹性格质)#>
      multiplier:<#(倍数)#>
      constant:<#(扩充的常量值)#>];
  • 加多封锁的平整:

    • 对于七个同层级view之间的束缚关系,加多到它们的父view上
    • 对于多个不等层级view之间的自律关系,加多到他俩近年来的联合父view上
    • 对此有档期的顺序关系的多少个view之间的牢笼关系,增多到档案的次序较高的父view上
  • 代码增添约束示例:

- (void)viewDidLoad {

    [super viewDidLoad];

    UIView *redView=[[UIView alloc] init];

    redView.backgroundColor=[UIColor redColor];

    [self.view addSubview:redView];

    //添加子控件

    UIView *blueView=[[UIView alloc] init];

    blueView.backgroundColor=[UIColor blueColor];

    [redView addSubview:blueView];

    //1.一定要禁用autoresizing

    redView.translatesAutoresizingMaskIntoConstraints=NO;

    blueView.translatesAutoresizingMaskIntoConstraints=NO;

    //2.创建约束

    //添加高度约束

    NSLayoutConstraint *constriantH=[NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0 constant:40];

    //设置顶部间距约束

    NSLayoutConstraint *constriantT=[NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:30];

    //设置左边间距约束

    NSLayoutConstraint *constriantL=[NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0];

    //设置右边间距约束

    NSLayoutConstraint *constriantR=[NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant:0];

    //添加蓝色view的约束

    NSLayoutConstraint *blueX=[NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:redView attribute:NSLayoutAttributeCenterX multiplier:1 constant:0];

    NSLayoutConstraint *blueH=[NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:redView attribute:NSLayoutAttributeHeight multiplier:1 constant:0];

    NSLayoutConstraint *blueR=[NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:redView attribute:NSLayoutAttributeRight multiplier:1 constant:0];

    NSLayoutConstraint *blueT=[NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:redView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:30];

    //添加约束到控件,注意添加的规则

    [redView addConstraint:constriantH];

    [self.view addConstraint:constriantT];

    [self.view addConstraint:constriantL];

    [self.view addConstraint:constriantR];

    [self.view addConstraint:blueX];

    [self.view addConstraint:blueH];

    [self.view addConstraint:blueR];

    [self.view addConstraint:blueT];

}

FiexibleHeight:父控件中度

这种景况正是view已经创立后处境栏会动态改换这种处境,而大家写代码的时候为了幸免出现bug也是必供给同盟这种状态的。这种情景除了前面说的用autolayout来创建视图,另一种办法就不得不监听状态栏改成的通告了,何况在接到通告后去动态的调治。

询问VFL语言的简便表明和选用–无需精晓
  • 什么是VFL语言:

    • 齐全都是Visual Format
      Language,翻译过来是“可视化格式语言”,是苹果公司为了简化Autolayout的编码而生产的肤浅语言
  • VFL语言的语法

![](https://upload-images.jianshu.io/upload_images/2229471-d1e803b4ef3aa625.png)
  • 例如;H:|-间距-[view1对象名]-(>=20)-[view2对象名]

    • H:表示水平方向,V表示垂直方向,不写H/V就代表横向
    • “|”是用来规定view上、下、左、右关系的,如若当前是H,那么就意味着水平方向的参照控件的左手也许左侧,尽管是V就象征参照控件的顶边大概底边
    • 假若是H,那些表明式就足以从左到右描述当前view及与参照view的关系,如若是V,类似。
    • 方括号表示view,圆括号表示尺寸数值。援救大小相等。只怕另一个view 如:H:|-[view1(view2)],v1的增长幅度等于v2
    • 先行级用@表示
    • 上边那句VFL代码的意味便是:view1离父控件左侧有三个区间,之后有三个view2控件,view2控件与view1控件有二个>=20的间隔。
  • VFL语言的选拔

UIView *redView=[[UIView alloc] init];
redView.backgroundColor=[UIColor redColor];
[self.view addSubview:redView];

//添加子控件
UIView *blueView=[[UIView alloc] init];
blueView.backgroundColor=[UIColor blueColor];
[self.view addSubview:blueView];

//1.一定要禁用autoresizing
redView.translatesAutoresizingMaskIntoConstraints=NO;
blueView.translatesAutoresizingMaskIntoConstraints=NO;

//2.创建约束

//2.1创建redView的顶部间距约束
NSString *redT=@"V:|-paddingT-[redView]-padding-[blueView]";
NSDictionary *redTmetrics=@{@"paddingT":@40,@"padding":@60};
NSDictionary *redTviews=@{@"redView":redView,@"blueView":blueView};
NSArray *redConT=[NSLayoutConstraint constraintsWithVisualFormat:redT options:0 metrics:redTmetrics views:redTviews];

//2.2创建redView的左右间距约束
NSString *redLR=@"H:|-paddingL-[redView]-paddingR-|";
NSDictionary *redLRmetrics=@{@"paddingL":@10,@"paddingR":@10};
//NSDictionary *redLRviews=@{@"redView":redView};
NSArray *redConLR=[NSLayoutConstraint constraintsWithVisualFormat:redLR options:0 metrics:redLRmetrics views:redTviews];

//2.3创建redView的高度约束
NSString *redH=@"V:[redView(44)]";
NSArray *redConH=[NSLayoutConstraint constraintsWithVisualFormat:redH options:0 metrics:nil views:redTviews];

//添加约束
[self.view addConstraints:redConT];
[self.view addConstraints:redConLR];
[redView addConstraints:redConH];

FiexibleBottoMargin:尾巴部分间距