Autoresizing / Autolayout / VFI / Masonry / sizeClasses

如何适配?

  • 不同版本适配
  • 不同屏幕尺寸适配,不同屏幕方向(横竖屏)

点与像素

  • 1、用户:屏幕是由无数个像素组成的,开发者:屏幕是由无数个点组成的,点又是由像素组成的
  • 2、非retina与retina屏
    • 非retina屏幕(3GS) : 1个点由1个像素组成
    • retina屏幕:1个点由2 x 2个像素组成

设备分辨率

fbl.png

自动布局的多种方式

1、Autoresizing

  • 都是约束父子关系, 所以Autoresizing只能约束父子控件之间的关系, 不能约束兄弟控件之间的关系

  • 方式一:storyboard实现

    • 注意: Storyboard中勾选上左边, 就代表当前控件和父控件的左边的距离是固定的


      Snip20151026_14.png
  • 方式二:纯代码实现

    • 注意1:代码中的上下左右和Storyboard中的是相反的
      • Storyboard中勾选上左边, -> 当前控件和父控件的左边的距离是固定的
      • 代码中如果写上FlexibleLeftMargin,->当前控件和父控件的左边是可拉伸的
  • 规律

     UIViewAutoresizingFlexibleLeftMargin // 左边可以伸缩
     UIViewAutoresizingFlexibleRightMargin // 右边可以伸缩
     UIViewAutoresizingFlexibleTopMargin // 顶部可以伸缩
     UIViewAutoresizingFlexibleBottomMargin // 底部可以伸缩
     
     // 以下两个和Storyboard中的是一样的
     UIViewAutoresizingFlexibleWidth // 宽度可以伸缩
     UIViewAutoresizingFlexibleHeight // 高度可以伸缩
  • 代码实现,红色View随着其父控件的宽度与高度拉伸而拉伸
    • 效果:


      Snip20151026_15.png
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    // 1.创建父控件
    UIView *greenView = [[UIView alloc] init];
    greenView.frame = CGRectMake(0, 0, 200, 200);
    greenView.backgroundColor = [UIColor greenColor];
    [self.view addSubview:greenView];
    self.greenView = greenView;
    
    // 2.创建子控件
    UIView *redView = [[UIView alloc] init];
    redView.frame = CGRectMake(0, 0, 100, 100);
    redView.backgroundColor = [UIColor redColor];
    [greenView addSubview:redView];
    
    // 3.设置子控件的autoresizing
   
    // 红色子控件,随着父控件,宽度与高度可拉伸
    redView.autoresizingMask = UIViewAutoresizingFlexibleWidth |
                               UIViewAutoresizingFlexibleHeight;
}

- (void)touchesBegan:(nonnull NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event
{
    self.greenView.frame =  CGRectMake(0, 0, 300, 300);   
}
  • 点击视图,让父控件宽高增大,子控件也随父控件拉伸了


    Snip20151026_17.png

Autolayout 自动布局

1、Autolayout 代码实现

  • 在创建约束之后,需要将其添加到作用的view上
  • 约束规则
    • 对于两个同层级view之间的约束关系,添加到它们的父view上


      1.png
    • 对于两个不同层级view之间的约束关系,添加到他们最近的共同父view上


      2.png
  • 对于有层次关系的两个view之间的约束关系,添加到层次较高的父view上


    3.png
  • 一个NSLayoutConstraint对象就代表一个约束
  • 创建约束对象的常用方法
+(id)constraintWithItem:(id)view1attribute:(NSLayoutAttribute)attr1relatedBy:(NSLayoutRelation)relationtoItem:(id)view2attribute:(NSLayoutAttribute)attr2multiplier:(CGFloat)multiplierconstant:(CGFloat)c;
  • 自动布局的核心计算公式
obj1.property1=(obj2.property2* multiplier)+constantvalue
需求:设置一个redView宽高100,现实在屏幕中间

+代码实现Autolayout的注意点

  • 1、如果通过代码来设置Autolayout约束, 那么必须先禁用Autoresizing
```objc

redView.translatesAutoresizingMaskIntoConstraints = NO;

   - 2、通过代码添加Autolayout约束, 添加约束之前必须保证控件已经在父控件上了
   - 3、不用再给view设置frame

+ 创建约束 方法分析: [NSLayoutConstraint constraintWithItem: .......]

```objc
   /*
     Item == first item
     attribute == first item需要设置的约束类型
     relatedBy == Relatio(等于)
     toItem ==  Second item
     attribute == Second item的约束类型
     multiplier == 乘以
     constant == 加上多少
     */
// redView 的 centerX = self.view的centerX * 1.0 + 0.0
NSLayoutConstraint *xCos = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0];
  • 代码实现
 // 1.创建控件
    UIView *redView = [[UIView alloc] init];
    redView.backgroundColor = [UIColor redColor];
    [self.view addSubview:redView];

2、基于Autolayout的动画

  • 注意: 强制更新界面:会更新当前控件和当前控件所有的子控件
 [添加了约束的view layoutIfNeeded];
  • 代码实现:动画
#import "ViewController.h"
@interface ViewController ()
// 约束
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *topCos;
@property (weak, nonatomic) IBOutlet UIView *redView;
@end

@implementation ViewController

- (void)touchesBegan:(nonnull NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event
{
    self.topCos.constant += 150;
    [UIView animateWithDuration:2.0 animations:^{
        // 强制更新界面
        // 会更新当前控件和当前控件所有的子控件
        [self.redView layoutIfNeeded];
    }];
}
@end

VFL添加约束

  • Visual Format Language,“可视化格式语言”,VFL是苹果公司为了简化Autolayout的编码而推出的抽象语言

  • VFL示例

H:[cancelButton(72)]-12-[acceptButton(50)]
pcanelButton宽72,acceptButton宽50,它们之间间距12

H:[wideView(>=60@700)]
pwideView宽度大于等于60point,该约束条件优先级为700(优先级最大值为1000,优先级越高的约束越先被满足)

V:[redBox][yellowBox(==redBox)]
竖直方向上,先有一个redBox,其下方紧接一个高度等于redBox高度的yellowBox

H:|-10-[Find]-[FindNext]-[FindField(>=20)]-|
水平方向上,Find距离父view左边缘默认间隔宽度,之后是FindNext距离Find间隔默认宽度;再之后是宽度不小于20的FindField,它和FindNext以及父view右边缘的间距都是默认宽度。(竖线“|”表示superview的边缘)
  • VFL的使用
    • 使用VFL来创建约束数组
pformat:VFL语句
popts:约束类型
pmetrics:VFL语句中用到的具体数值
pviews:VFL语句中用到的控件
+(NSArray*)constraintsWithVisualFormat:(NSString*)format options:(NSLayoutFormatOptions)optsmetrics:(NSDictionary*)metrics views:(NSDictionary*)views;
  • 创建一个字典(内部包含VFL语句中用到的控件)的快捷宏定义
NSDictionaryOfVariableBindings(...)
Snip20151026_18.png

Masonry 第三方框架

  • 注意: 在Storyboard中约束是可以重复添加的, 通过Masonry添加约束也是可以重复的, 要注意重复添加导致的错误和冲突
  • 添加、更新、移除约束
    • 添加约束 makeConstraints:
      • 每次都会添加新的约束, 也就是会导致重复添加

[self.blueVeiw makeConstraints:^(MASConstraintMaker *make) {
// make.height.equalTo(100);
// }];

+ 更新约束  updateConstraints  
  - 特点: 如果没有设置过, 就添加一个新的,如果已经设置过了, 就更新以前设置的那一个
```objc
[self.blueVeiw updateConstraints:^(MASConstraintMaker *make) {
     make.height.equalTo(100);
 }];
  • 清空约束 remakeConstraints
[self.blueVeiw remakeConstraints:^(MASConstraintMaker *make) {
        
    }];
  • 1、添加简化宏定义
#import "ViewController.h"

//define this constant if you want to use Masonry without the 'mas_' prefix
#define MAS_SHORTHAND 
// 只要添加这个宏, 就可以去掉Masonry框架中对象访问对象属性前面的mas_属性, 和方法前的mas_前缀

// 例如添加前的写法
/*
 make.left.equalTo(self.view.mas_left).with.offset(20);
 */
// 例如添加后的写法
/*
 make.left.equalTo(self.view.left).with.offset(20);
 */

//define this constant if you want to enable auto-boxing for default syntax
#define MAS_SHORTHAND_GLOBALS
// 只要添加上这个宏, 给equalTo传递参数的时候, 就可以直接传递基本数据类型 ,系统会自动包装
// 如果没有添加上面这个宏, 那么给equalTo传递参数的时候, 必须传递对象
// 如果要传递基本数据类型必须使用mas_equalTo
// 只需要在导入Masonry.h之前, 添加上面的两个宏, 就可以简化代码
#import "Masonry.h"
  • 2、实现红色view是蓝色宽度一半。。。。


    Snip20151026_19.png
 // 1.创建两个View, 并且添加到父控件
    UIView *blueVeiw = [[UIView alloc] init];
    blueVeiw.backgroundColor = [UIColor blueColor];
    [self.view addSubview:blueVeiw];
    self.blueVeiw = blueVeiw;
    
    UIView *redVeiw = [[UIView alloc] init];
    redVeiw.backgroundColor = [UIColor redColor];
    [self.view addSubview:redVeiw];
    
    // 2.禁止红色View的Autgoresizing
    blueVeiw.translatesAutoresizingMaskIntoConstraints = NO;
    redVeiw.translatesAutoresizingMaskIntoConstraints = NO;
    
    // 3.添加蓝色的约束
    [blueVeiw makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.view.left).offset(20);
        make.right.equalTo(self.view.right).offset(-20);
        make.top.equalTo(self.view.top).offset(20);
        make.height.equalTo(50);
    }];
    
    // 4.添加红色的约束
    [redVeiw makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(blueVeiw.bottom).offset(20);
        make.height.equalTo(blueVeiw.height);
        make.right.equalTo(blueVeiw.right);
        make.width.equalTo(blueVeiw.width).multipliedBy(0.5);
    }];

sizeClasses

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

推荐阅读更多精彩内容