iOS 屏幕适配

在做屏幕适配前,首先需要了解iPhone各型号的屏幕,
这里写图片描述
注:7与7+的屏幕同6与6+

iPad 的屏幕:
这里写图片描述

接下来,明确一个概念-像素密度PPI(Pixel Per Inch by diagonal),即沿着对角线,每英寸所拥有的像素(Pixel)数目。PPI越高,说明屏幕显示图像的密度越高,即通常所说的分辨率越高。(PPI *对角线)的平方 = 屏幕高的平方+屏幕宽的平方;后来在iPhone4中,采用了Retina显示技术,横、纵向方向像素密度都被放大到2倍,iPhone4与iPhone3具有同样大小的屏幕,但分辨率提升了4倍(1个Point被渲染成1个2x2的像素矩阵)。对于 iOS 开发者来说,iOS 绘制图形的API以point(pt)为单位,在iPhone4-iPhone6中,1个point = 2个pixel,iPhone6+,1个point = 3个pixel。

一、根据屏幕的宽高比例适配
iPhone4~6(+)的屏幕高宽比:
iPhone4(s):分辨率960*640,高宽比1.5
iPhone5(s):分辨率1136*640,高宽比1.775
iPhone6:分辨率1334*750,高宽比1.779
iPhone6+:分辨率1920*1080,高宽比1.778
可选定一个屏幕的宽高为基准,利用宽高比,在不同的屏幕中来进行对控件的位置与控件的宽高进行等比例缩放,但要注意,iPhone4与iPhone5的宽都为320,但高度不同,可以获得宽比例和高比例,同时使用宽高比例。

//获得当前屏幕宽与6的屏宽比例
#define RATIO_W [UIScreen mainScreen].bounds.size.width/375
//获得当前屏幕高与6的屏高比例
#define RATIO_H [UIScreen mainScreen].bounds.size.height/667
//设置frame时使用
#define CGRATIONRect(x,y,w,h) CGRectMake(x*RATIO_W, y*RATIO_H, w*RATIO_W, h*RATIO_H)

二、使用AutoLayout进行屏幕适配
AutoLayout关键就是约束和参照,首先介绍它的一个类方法:+(instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c,该方法返回一个NSLayoutConstraint对象;
view1—传入想要添加约束的控件
attr1—传入想要添加约束的方向(枚举)
relation—传入与约束值的关系,大于,等于还是小于
view2—传入被参照对象
attr2—传入被参照对象所被参照的方向
multiplier—传入想要的间距倍数关系
c —传入最终的差值
先简单的创建一个view1

 //创建一个视图,背景色为红色
    UIView * view1 = [[UIView alloc]init];
    view1.backgroundColor = [UIColor redColor];
    view1.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:view1];
    //为view1添加约束,距离self.view左边缘20
    NSLayoutConstraint * view1Left = [NSLayoutConstraint constraintWithItem:view1 attribute:(NSLayoutAttributeLeft) relatedBy:(NSLayoutRelationEqual) toItem:self.view attribute:(NSLayoutAttributeLeft) multiplier:1.0 constant:20.0];
    //为view1添加约束,距离self.view上方20
    NSLayoutConstraint * view1Top = [NSLayoutConstraint constraintWithItem:view1 attribute:(NSLayoutAttributeTop) relatedBy:(NSLayoutRelationEqual) toItem:self.view attribute:(NSLayoutAttributeTop) multiplier:1.0 constant:20.0];
    //为view1添加约束,宽度为self.view的一半
    NSLayoutConstraint * view1Width = [NSLayoutConstraint constraintWithItem:view1 attribute:(NSLayoutAttributeWidth) relatedBy:(NSLayoutRelationEqual) toItem:self.view attribute:(NSLayoutAttributeWidth) multiplier:0.5 constant:0];
    //为view1添加约束,高度为30,无参照控件
    NSLayoutConstraint * view1Height = [NSLayoutConstraint constraintWithItem:view1 attribute:(NSLayoutAttributeHeight) relatedBy:(NSLayoutRelationEqual) toItem:nil attribute:kNilOptions multiplier:1.0 constant:50.0];
    //添加约束至view1的父控件
    [self.view addConstraint:view1Left];
    [self.view addConstraint:view1Top];
    [self.view addConstraint:view1Width];
    [self.view addConstraint:view1Height];

再创建一个依赖view1的view2

UIView * view2 = [[UIView alloc]init];
    view2.backgroundColor = [UIColor blueColor];
    view2.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:view2];

    //为view2添加约束,与view1坐距离相同
    NSLayoutConstraint * view2Left = [NSLayoutConstraint constraintWithItem:view2 attribute:(NSLayoutAttributeLeft) relatedBy:(NSLayoutRelationEqual) toItem:view1 attribute:(NSLayoutAttributeLeft) multiplier:1.0 constant:0];
    //为view2添加约束,与view1相隔20
    NSLayoutConstraint * view2Top = [NSLayoutConstraint constraintWithItem:view2 attribute:(NSLayoutAttributeTop) relatedBy:(NSLayoutRelationEqual) toItem:view1 attribute:(NSLayoutAttributeBottom) multiplier:1.0 constant:20.0];
    //为view2添加约束,与view1同宽
    NSLayoutConstraint * view2Width = [NSLayoutConstraint constraintWithItem:view2 attribute:(NSLayoutAttributeWidth) relatedBy:(NSLayoutRelationEqual) toItem:view1 attribute:(NSLayoutAttributeWidth) multiplier:1.0 constant:0];
    //为view2添加约束,等宽高
    NSLayoutConstraint * view2Height = [NSLayoutConstraint constraintWithItem:view2 attribute:(NSLayoutAttributeHeight) relatedBy:(NSLayoutRelationEqual) toItem:view2 attribute:(NSLayoutAttributeWidth) multiplier:1.0 constant:0];
     //添加约束至view2的父控件
    [self.view addConstraint:view2Left];
    [self.view addConstraint:view2Top];
    [self.view addConstraint:view2Width];
    [view2 addConstraint:view2Height];

使用AutoLayout适配时,需注意不要重复添加约束,也不要有约束冲突,若造成了约束冲突,可添加优先级来解决,优先级的范围是0~1000,数字越大,优先级越高,不设置的情况下默认为1000。

//为view2添加另外的约束,距离self.view底部20,与view2的等宽高约束冲突,若都采用默认优先级,运行证明该约束的优先级更高
    NSLayoutConstraint * elseConstraint = [NSLayoutConstraint constraintWithItem:view2 attribute:(NSLayoutAttributeBottom) relatedBy:(NSLayoutRelationEqual) toItem:self.view attribute:(NSLayoutAttributeBottom) multiplier:1.0 constant:20.0];
    //设置优先级
    UILayoutPriority priority = 500;
    //添加优先级
    elseConstraint.priority = priority;
    //再运行,view2依然等宽高
    [self.view addConstraint:elseConstraint];

AutoLayout还提供另外的方法:+ (NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary *)metrics views:(NSDictionary *)views;返回一个数组。该方法使用的是Visual Format Language,此方法,个人觉得参数太复杂,不好用。
format—传入某种格式构成的字符串,用以表达想要添加的约束;
opts—对齐方式(枚举);
metrics— 一般传入以间距为KEY的字典,KEY要与format参数里所填写的“margin”相同;
views—传入约束中提到的View,也是要传入字典,但是KEY一定要和format参数里所填写的View名字相同;
在format参数中,@”H:”—水平方向;@”V:”—垂直方向;@”|”—边界;@”-“—间隙;@”[]”—括号里是要添加约束的View。
列如创建一个view1

    //创建第一个视图,背景色为红色
    UIView * view1 = [[UIView alloc]init];
    view1.backgroundColor = [UIColor redColor];
    view1.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:view1];
     //设置水平方向约束,距离左边界20,宽50
    NSString * hConstrain1 = @"H:|-20-[view(50)]";;
    //设置水平方向约束,距离上边界20,高60
    NSString * vConstrain1 = @"V:|-20-[view1(60)]";
    //生成水平约束
    NSArray * arr1 = [NSLayoutConstraint constraintsWithVisualFormat:hConstrain1 options:NSLayoutFormatAlignAllLeft metrics:nil views:@{@"view1":view1}];
    //生成竖直约束
    NSArray * arr2 = [NSLayoutConstraint constraintsWithVisualFormat:vConstrain1 options:(NSLayoutFormatAlignAllTop) metrics:nil views:@{@"view1":view1}];
    //添加约束
    [self.view addConstraints:arr1];
    [self.view addConstraints:arr2];

创建多个有依赖关系的视图

    //创建第二个视图,背景色为红色
    UIView * view2 = [[UIView alloc]init];
    view2.backgroundColor = [UIColor yellowColor];
    view2.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:view2];

    //创建第三个视图,背景色为红色
    UIView * view3 = [[UIView alloc]init];
    view3.backgroundColor = [UIColor blueColor];
    view3.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:view3];

    //设置水平方向约束,距离左边界20,宽50
    NSString * hConstrain1 = @"H:|-margin1-[v1(50)]-margin2-[v2(60)]-margin3-[v3(==v1)]";;
    //设置水平方向约束,距离上边界20,高60
    NSString * vConstrain1 = @"V:|-20-[view1(60)]";
    NSLayoutFormatOptions ops = NSLayoutFormatAlignAllTop|NSLayoutFormatAlignAllBottom;
    //生成水平约束
    NSArray * arr1 = [NSLayoutConstraint constraintsWithVisualFormat:hConstrain1 options:ops metrics:@{@"margin1":@10,@"margin2":@20,@"margin3":@30} views:@{@"v1":view1,@"v2":view2,@"v3":view3}];
    //生成竖直约束
    NSArray * arr2 = [NSLayoutConstraint constraintsWithVisualFormat:vConstrain1 options:(NSLayoutFormatAlignAllTop) metrics:nil views:@{@"view1":view1}];

    //添加约束
    [self.view addConstraints:arr1];
    [self.view addConstraints:arr2];

三、使用Masonry进行屏幕适配
Masonry的语言简洁,是一款非常受欢迎的屏幕适配框架,Masonry下载地址。Masonry非常容易理解,想要熟练的使用还需要靠自己去实践,这里写了一些基本的用法,大家可以查看Masonry的源码去好好研究。

//创建第一个视图,背景色为红色
    UIView * view1 = [[UIView alloc]init];
    view1.backgroundColor = [UIColor redColor];
    [self.view addSubview:view1];

    //创建第二个视图,背景色为黄色
    UIView * view2 = [[UIView alloc]init];
    view2.backgroundColor = [UIColor yellowColor];
    [self.view addSubview:view2];

    //创建第三个视图,背景色为蓝色
    UIView * view3 = [[UIView alloc]init];
    view3.backgroundColor = [UIColor blueColor];
    [self.view addSubview:view3];

    [view1 mas_makeConstraints:^(MASConstraintMaker *make) {
        //距离坐边界10.0
        make.left.equalTo(self.view.mas_left).offset(10.0);
        //距离上边界10.0
        make.top.equalTo(self.view.mas_top).offset(10.0);
        //宽为屏宽的30%
        make.width.equalTo(self.view.mas_width).multipliedBy(0.3);
        //高为屏高的10%
        make.height.equalTo(self.view.mas_height).multipliedBy(0.1);
    }];

    [view2 mas_makeConstraints:^(MASConstraintMaker *make) {
         //与view1的右边界相邻
        make.left.equalTo(view1.mas_right);
        //与view1的上边界相同
        make.top.equalTo(view1.mas_top);
         //宽、高为view1宽相同
        make.width.and.height.equalTo(view1);
    }];

    [view3 mas_makeConstraints:^(MASConstraintMaker *make) {
        //与view1的左边界相同
        make.leading.equalTo(view1);
        //距离view1的下边界10
        make.top.equalTo(view1.mas_bottom).offset(10.0);
        //view1的宽的80%加10
        make.width.equalTo(view1.mas_width).multipliedBy(0.8).offset(10.0);
        //view1的高的80%减10
        make.height.equalTo(view1.mas_height).multipliedBy(0.8).offset(-10.0);
    }];

四、storyboard实现Autolayout
storyboard中实现屏幕适配其实就是将代码视图化,也是通过设置constraint等,这里给大家推荐一遍讲解很详细的博客:storyboard实现Autolayout,希望大家能从中有所收获。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值