自动布局:AutoLayout代码实现:NSLayoutConstraint、VFL、Mansony

一、注意事项

1、使用AutoLayout自动布局,全程都不要出现和frame相关的代码了,不要设置frame。

2、在使用AutoLayout自动布局的时候,要先把视图添加到父视图中。

3、设置 AutoLayout 约束,之前先禁用AutoResizing ,在代码里只需要针对某一个视图决定是使用 AutoResizing 还是 使用 AutoLayout。

    // “不把AutoResizing设置翻译成AutoLayout约束”
    redView.translatesAutoresizingMaskIntoConstraints = NO;


二、第一种方法,Xcode提供的最原始的方法,编写核心公式方法

核心公式:item1.attr1 = item2.attr2 * multiplier + constant

/* accessors
 firstItem.firstAttribute {==,<=,>=} secondItem.secondAttribute * multiplier + constant
 */
@property (readonly, assign) id firstItem;
@property (readonly) NSLayoutAttribute firstAttribute;
@property (readonly) NSLayoutRelation relation;
@property (nullable, readonly, assign) id secondItem;
@property (readonly) NSLayoutAttribute secondAttribute;
@property (readonly) CGFloat multiplier;

@property CGFloat constant;


NSLayoutAttribute 和 NSLayoutRelation 都是枚举类型。

    /* Create constraints explicitly.  Constraints are of the form "view1.attr1 = view2.attr2 * multiplier + constant"
     If your equation does not have a second view and attribute, use nil and NSLayoutAttributeNotAnAttribute.
     */
    +(instancetype)constraintWithItem:(id)view1
                            attribute:(NSLayoutAttribute)attr1
                            relatedBy:(NSLayoutRelation)relation
                               toItem:(nullable id)view2
                            attribute:(NSLayoutAttribute)attr2
                           multiplier:(CGFloat)multiplier
                             constant:(CGFloat)c;
如果没有view2没有,那么view2设置为nil,attr2设置为NSLayoutAttributeNotAnAttribute。

然后调用addConstraint。

注意:

1)一点要先把视图添加到父试图里面,再设置约束。

2)如果将约束条件添加到另一个无关系的视图上,会报错。错误信息类似如下:
The view hierarchy is not prepared for the constraint.

When added to a view, the constraint's items must be descendants of that view (or the view itself). This will crash if the constraint needs to be resolved before the view hierarchy is assembled.

Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to install constraint on view. Does the constraint reference something from outside the subtree of the view? That's illegal.

3)如果没有设置transtraintAtuoResizingIntoConstraint为No,错误信息:
Probably at least one of the constraints in the following list is one you don't want.


三、第二种方法:Xcode提供的VFL(可视化格式语言)

• VFL 语法
H: 水平方向
V: 垂直方向
| 边界
[视图名称]
(约束值)
= >= <= 关系
- 距离

使用实例:

    txf1.translatesAutoresizingMaskIntoConstraints = NO;
    txf2.translatesAutoresizingMaskIntoConstraints = NO;
    
    //使用VFL语言添加约束
    NSDictionary *dictMetrics = @{@"widthMargin":@20,@"heigthMargin":@20};
    NSDictionary *dictViews = @{@"TextField1":txf1, @"TextField2":txf2};
    
    NSString *strVFLTxf1_1 = @"H:|-widthMargin-[TextField1]-widthMargin-|";
    NSString *strVFLTxf1_2 = @"V:|-heigthMargin-[TextField1(==30)]";
    NSString *strVFLTxf2_1 = @"H:|-widthMargin-[TextField2]-widthMargin-|";
    NSString *strVFLTxf2_2 = @"V:[TextField1]-heigthMargin-[TextField2(==TextField1)]";
    
    NSArray *arrVflConsts1 = [NSLayoutConstraint constraintsWithVisualFormat:strVFLTxf1_1 options:NSLayoutFormatDirectionLeftToRight metrics:dictMetrics views:dictViews];
    [self.view addConstraints:arrVflConsts1];
注意:

constraintsWithVisualFormat 返回值是 约束条件的数组,添加约束条件时使用的 addConstraints。

四、第三种方法:使用第三方框架Mansony

    [blueView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.height.centerX.equalTo(redView);
        make.width.equalTo(redView).multipliedBy(0.5);
        make.bottom.equalTo(redView.mas_top).offset(-20);
    }];

注意:

1) masonry框架在使用的时候自动把视图的AutoResizing禁用掉了。

2)如果item1的attr 和 对照项 item2的attr相同,可以省略make.centerX.equalTo(self.view);

3)使用mas_equalTo不需要给数字装箱。make.width.mas_equalTo(20);

4)使用masonry制作AutoLayout动画时,在更新约束的时候不能更新之前没有设置的约束,否则要重建约束。

5)两个宏

//define this constant if you want to use Masonry without the  mas_  prefix
// 如果不希望使用 mas_ 前缀,可以定义此常量
#define MAS_SHORTHAND

//define this constant if you want to enable auto-boxing for default syntax
// 如果希望启动 自动装箱 ,可以定义此常量
// 所谓 自动装箱 ,就是能够自动将结构体包装成  NSValue ,而无需再使用  mas_equalTo 
#define MAS_SHORTHAND_GLOBALS

6)三个重要方法

mas_updateConstraints 只能更新已经建立的约束,如果约束不存在,会在控制台输出错误

mas_remakeConstraints 清除原来的约束 重新设置约束;

mas_makeConstraints 只负责新增约束,Autolayout 不能同时存在两条针对于同一对象约束 否则会报错
注意:在添加约束之前一定要添加到view( [testView addSubview:self.view])上 否则会报错


阅读更多
个人分类: iOS
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭