Autolayout~代码实现

代码添加约束一般是四个步骤

1.创建需要约束的视图并且设置视图的translatesAutoresizingMaskIntoConstraints = NO(不设置这个约束不生效)

2.将视图添加到其父视图上

3.创建约束

4.添加约束

使用约束需要将视图的关系(添加到父视图或者其他视图树的关系)处理完成后在添加约束,否则有可能会试图错乱并且控制台会输出警告信息

 

代码添加约束是通过NSLayoutConstraint进行添加的,

/* Create an array of constraints using an ASCII art-like visual format string.
 */
+ (NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary *)metrics views:(NSDictionary *)views;

/* This macro is a helper for making view dictionaries for +constraintsWithVisualFormat:options:metrics:views:.  
 NSDictionaryOfVariableBindings(v1, v2, v3) is equivalent to [NSDictionary dictionaryWithObjectsAndKeys:v1, @"v1", v2, @"v2", v3, @"v3", nil];
 */
#define NSDictionaryOfVariableBindings(...) _NSDictionaryOfVariableBindings(@"" # __VA_ARGS__, __VA_ARGS__, nil)
UIKIT_EXTERN NSDictionary *_NSDictionaryOfVariableBindings(NSString *commaSeparatedKeysString, id firstValue, ...) NS_AVAILABLE_IOS(6_0); // not for direct use


/* 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.
 */
+(id)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;

上面是头文件中两种创建

第一种是创建一组约束,用苹果提供的一套格式化语言,叫做visual format language,这个需要单独学习

第二种是创建一个约束,第一个参数是指定要约束的视图,第二个参数是要约束的属性(一个枚举类型),第三个参数是要约束的视图属性和参照视图属性的关系(相等,较大或者较小),第四个参数是参照视图,第五个参数是参照视图的参照属性,第六个参数是一个要乘以的数字,第七个参数是约束的值

可由注释中的式子来计算要约束的视图和参照视图之间的关系view1.attr1 = view2.attr2 * multiplier + constant

 

下面是一段简单的创建视图并添加约束的代码,你可以自己粘过去运行一下,看一下效果 

[super viewDidLoad];
    
    // 1. 创建要约束的视图
    UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [button setBackgroundColor:[UIColor greenColor]];
    // 1.1 设置translatesAutoresizingMaskIntoConstraints为NO,使autoLayout生效
    button.translatesAutoresizingMaskIntoConstraints = NO;
    
    // 2. 添加到父视图
    [self.view addSubview:button];

    // 3.创建约束
    // 3.1 button的左边界距离俯视图左边界100个距离
    NSLayoutConstraint *conX = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:100];
    // 3.2button上边界距离父视图上边界100个距离
    NSLayoutConstraint *conY = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:100];
    // 3.3 button宽度固定为100
    NSLayoutConstraint *buttonW = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:1.0 constant:100];
    // 3.4 button固定高度为100
    NSLayoutConstraint *buttonH = [NSLayoutConstraint constraintWithItem:button attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:1.0 constant:100];
    
    // 4 将约束添加到视图上
    [self.view addConstraint:conX];
    [self.view addConstraint:conY];
    [button addConstraint:buttonW];
    [button addConstraint:buttonH];

 

你可以看到代码中中的约束有的添加到了父视图上,有的添加到了button上

如果你使用IB添加约束,你就可以看到,如果约束只与控件本身有关系,那么约束一般添加到控件自身上就好了(也可以添加到父控件上,因为父控件可以约束自己的子控件),如果是控件与父控件之间的关系约束,那么这个必须添加到父控件上(否则会崩溃)

如果是没有父子关系的两个View之间的约束,那么这个约束需要添加到他们共同的一个superView.superView上去,确保是他们共同的父父父视图,看下图

如果创建的约束是F和G之间的约束,这个约束需要添加到C上或者C的父视图A上,或者更上层的视图才能保证程序正常运行

,因为只有C或者其父视图才能同时看到F和G并约束他们

 

 

如果不学习苹果的visual format并且公司不允许使用IB,那就需要一个一个写约束了,这时候就比较蛋疼了

好在有github上有一个轻量级的布局框架叫Masonry,有兴趣的可以研究下~

 

posted @ 2014-10-23 15:13  784692237  阅读(511)  评论(0编辑  收藏  举报