代码添加constraint,设置translatesAutoresizingMaskIntoConstraints为NO的原因

来源:互联网 发布:php artisan db seed 编辑:程序博客网 时间:2024/05/23 17:25

代码addSubview,如果想用相对布局,记得 subview的translatesAutoresizingMaskIntoConstraints设置为NO,否则会有autoresize生成的constraints,导致冲突;
而在Interface Builder中勾选了Ues Autolayout,IB生成的控件的translatesAutoresizingMaskIntoConstraints属性都会被默认设置NO.


在用代码为控件添加NSLayoutConstraint的时候,有时会遇到以下错误:

Unable to simultaneously satisfy constraints.

Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 

这种错误在编译阶段又无法被查出。这时,我们在检查了自己的constraint之后,确认constraint没有逻辑错误,可能就是没有在对应的view添加以下代码

[view setTranslatesAutoresizingMaskIntoConstraints:NO];

那这一行代码有何作用呢?

在Programming IOS 7(第四版)有这么一段话:

Layout is performed in three primary ways:

Manual layout

       The superview is sent the layoutSubviews message whenever it is resized; so, to

       lay out subviews manually, provide your own subclass and override layout-

       Subviews. Clearly this could turn out to be a lot of work, but it means you can do

       anything you like.

Autoresizing

......

Autolayout

......

就是说layout有三种方式:Manual layout,Autoresizing,Autolayout。我们常用的可能就后面两种。

假设v1是一个不使用autolayout的view,而v2是一个使用autolayout的view,但v1成为v2的subview时,

v2需要四条隐含的constraint来确定v1的位置,这些约束都是从v1的frame转化而来:

This conversion is performed only if the view in question has its translates-

AutoresizingMaskIntoConstraints property set to YES. That is, in fact, the default if

the view came into existence either in code or by instantiation from a nib where “Use

Auto Layout” is not checked. The assumption is that if a view came into existence in

either of those ways, you want its frame and autoresizingMask to act as its constraints

if it becomes involved in autolayout.



[objc] view plaincopy
  1. - (void)viewDidLoad {  
  2.     [super viewDidLoad];  
  3.       
  4.     [self.view setTranslatesAutoresizingMaskIntoConstraints:NO];  
  5.     self.v1 = [[UIView alloc]initWithFrame:CGRectMake(200200100100)];  
  6.     self.v1.backgroundColor = [UIColor greenColor];  
  7.       
  8.     self.v2 = [UIView new];  
  9.     self.v2.backgroundColor = [UIColor redColor];  
  10.     [self.view addSubview:self.v2];  
  11.     self.v2.translatesAutoresizingMaskIntoConstraints = NO;  
  12.     //self.v1.translatesAutoresizingMaskIntoConstraints = NO;  
  13.     NSDictionary * viewDic = [[NSDictionary alloc]initWithObjectsAndKeys:self.v2,@"v2"self.v1,@"v1",nil];  
  14.     [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-100-[v2]-100-|" options:0 metrics:nil views:viewDic]];  
  15.     [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-100-[v2]-100-|" options:0 metrics:nil views:viewDic]];  
  16.       
  17.       
  18.     [self.v2 addSubview:self.v1];  
  19.     [self.v2 addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-100-[v1]-100-|" options:0 metrics:nil views:viewDic]];  
  20.   
  21. }  


上面代码会产生以下错误(Unable to simultaneously satisfy constraints.) ,即不能满足所有约束。容易看出,添加在v2上的constraint没有问题。是v1的隐含constraint和后来添加的constriaint产生了冲突



但是v1还能显示,(这个问题还没想明白):



但是去掉下面这一行的注释,再运行

[objc] view plaincopy
  1. //self.v1.translatesAutoresizingMaskIntoConstraints = NO;  
v1无法显示:


显然,v1在translatesAutoresizingMaskIntoConstraints 设置为NO之后,没有添加隐含constraint,而代码添加的constraint又不足以确定v1的位置和大小,所以v1无法显示;



由于代码添加constraint很难检查出错误,所以我尽量避免代码编写constraint。但storyboard有时操作又比较麻烦,且不够灵活,有时就需要自己添加部分的代码来弥补storyboard的不足。

比如,我们要添加十几个按钮,这些按钮功能有基本一致,样式也一样,这时用storyboard编写就显得麻烦。以下代码向一个view中添加了12个按钮。并设置了他们的constraint

[objc] view plaincopy
  1. <span style="font-size:14px;">- (void)viewDidLoad {  
  2.     [super viewDidLoad];  
  3.       
  4.     [self.view setTranslatesAutoresizingMaskIntoConstraints:NO];  
  5.     NSDictionary * keyDetail;  
  6.     UIView * secondItem = self.view;  
  7.     keyDetail = [[NSDictionary alloc]initWithObjectsAndKeys:  
  8.                  @"F1",@"101",  
  9.                  @"F2",@"102",  
  10.                  @"F3",@"103",  
  11.                  @"F4",@"104",  
  12.                  @"F5",@"105",  
  13.                  @"F6",@"106",  
  14.                  @"F7",@"107",  
  15.                  @"F8",@"108",  
  16.                  @"F9",@"109",  
  17.                  @"F10",@"110",  
  18.                  @"F11",@"111",  
  19.                  @"F12",@"112",  
  20.                  nil nil];  
  21.     CGFloat keyHeightParameter = 30.0;  
  22.     CGFloat keyWidthParameter = 10;  
  23.     CGFloat keyspaceHorizontal = keyWidthParameter*keyDetail.count/(keyDetail.count+1);  
  24.     CGFloat keyspaceVertical = 200.0;  
  25.     int i;  
  26.     for(i = 1; i <= keyDetail.count; i++)  
  27.     {  
  28.         UIButton * key = [[UIButton alloc]init];  
  29.         key.tag = i+100 ;  
  30.           
  31.         [key setTranslatesAutoresizingMaskIntoConstraints:NO];  
  32.           
  33.         [key setTitle:[keyDetail valueForKey:[NSString stringWithFormat:@"%i",i+100]] forState:UIControlStateNormal];  
  34.         [key setTitleColor:[UIColor colorWithRed:49.0/255.0 green:69.0/255.0 blue:116.0/255.0 alpha:1.0] forState:UIControlStateNormal];  
  35.         [key setTitleColor:[UIColor colorWithRed:49.0/255.0 green:69.0/255.0 blue:116.0/255.0 alpha:1.0] forState:UIControlStateSelected];  
  36.         key.titleLabel.font = [UIFont systemFontOfSize:14.0];  
  37.         [key setBackgroundColor:[UIColor whiteColor]];  
  38.         key.layer.borderColor = [UIColor grayColor].CGColor;  
  39.         key.layer.borderWidth = 0.5;  
  40.         key.layer.cornerRadius = 10;  
  41.           
  42.         [self.view addSubview:key];  
  43.         if (secondItem == self.view)  
  44.         {  
  45.             [self.view addConstraint:[NSLayoutConstraint constraintWithItem:key attribute:NSLayoutAttributeLeading  
  46.                                                                   relatedBy:NSLayoutRelationEqual  
  47.                                                                      toItem:secondItem  
  48.                                                                   attribute:NSLayoutAttributeLeading  
  49.                                                                  multiplier:1 constant:keyspaceHorizontal]];  
  50.         }  
  51.         else  
  52.         {  
  53.             [self.view addConstraint:[NSLayoutConstraint constraintWithItem:key attribute:NSLayoutAttributeLeading  
  54.                                                                   relatedBy:NSLayoutRelationEqual  
  55.                                                                      toItem:secondItem  
  56.                                                                   attribute:NSLayoutAttributeTrailing  
  57.                                                                  multiplier:1 constant:keyspaceHorizontal]];  
  58.         }  
  59.           
  60.         [self.view addConstraint:[NSLayoutConstraint constraintWithItem:key attribute:NSLayoutAttributeTop  
  61.                                                               relatedBy:NSLayoutRelationEqual  
  62.                                                                  toItem:self.view attribute:NSLayoutAttributeTop  
  63.                                                              multiplier:1.0 constant:keyspaceVertical]];  
  64.         [self.view addConstraint:[NSLayoutConstraint constraintWithItem:key  
  65.                                                               attribute:NSLayoutAttributeWidth  
  66.                                                               relatedBy:NSLayoutRelationEqual  
  67.                                                                  toItem:self.view attribute:NSLayoutAttributeWidth  
  68.                                                              multiplier:1.0/keyDetail.count constant:-keyWidthParameter]];  
  69.         [key addConstraint:[NSLayoutConstraint constraintWithItem:key  
  70.                                                         attribute:NSLayoutAttributeHeight  
  71.                                                         relatedBy:NSLayoutRelationEqual  
  72.                                                            toItem:nil  
  73.                                                         attribute:NSLayoutAttributeNotAnAttribute  
  74.                                                        multiplier:1.0 constant:keyHeightParameter]];  
  75.           
  76.         secondItem = key;  
  77.     }  
  78. }</span>  

效果如下:

landscape:



portrait:



在这个过程中遇到一个错误:

        The view hierarchy is not prepared for the constraint:

        这种错误一般都是constrain与控件不对应,或者是subview没有加到superview中。

0 0
原创粉丝点击