Autoresizing / Autolayout / VFI / Masonry / sizeClasses

如何适配?

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

点与像素

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

设备分辨率

Autoresizing / Autolayout / VFI / Masonry / sizeClasses_第1张图片
fbl.png

自动布局的多种方式

1、Autoresizing

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

  • 方式一:storyboard实现

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


      Autoresizing / Autolayout / VFI / Masonry / sizeClasses_第2张图片
      Snip20151026_14.png
  • 方式二:纯代码实现

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

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


      Autoresizing / Autolayout / VFI / Masonry / sizeClasses_第3张图片
      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 *)touches withEvent:(nullable UIEvent *)event
{
    self.greenView.frame =  CGRectMake(0, 0, 300, 300);   
}
  • 点击视图,让父控件宽高增大,子控件也随父控件拉伸了


    Autoresizing / Autolayout / VFI / Masonry / sizeClasses_第4张图片
    Snip20151026_17.png

Autolayout 自动布局

1、Autolayout 代码实现

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


      Autoresizing / Autolayout / VFI / Masonry / sizeClasses_第5张图片
      1.png
    • 对于两个不同层级view之间的约束关系,添加到他们最近的共同父view上


      Autoresizing / Autolayout / VFI / Masonry / sizeClasses_第6张图片
      2.png
  • 对于有层次关系的两个view之间的约束关系,添加到层次较高的父view上


    Autoresizing / Autolayout / VFI / Masonry / sizeClasses_第7张图片
    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 *)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(...)
Autoresizing / Autolayout / VFI / Masonry / sizeClasses_第8张图片
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是蓝色宽度一半。。。。


    Autoresizing / Autolayout / VFI / Masonry / sizeClasses_第9张图片
    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:正常的
Autoresizing / Autolayout / VFI / Masonry / sizeClasses_第10张图片
Snip20151026_20.png

你可能感兴趣的:(Autoresizing / Autolayout / VFI / Masonry / sizeClasses)