创建程序化布局约束
创建程序化布局约束
我知道有很多人已经问过很多关于这个的问题,但即使有了答案,我也无法使它正常工作。当我处理故事板上的限制时很容易,但在代码中我很难。例如,我尝试使视图在右侧保持,并且根据屏幕方向具有屏幕高度。这是我的代码:
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 748)]; myView.backgroundColor = [UIColor redColor]; [self.view addSubview:myView]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[myView(>=748)]-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(myView)]];
它不能满足某些限制。我不知道哪里有问题。另外,为什么不能像使用本地变量myView
那样使用属性,比如self.myView
?
嗨,我一直在使用这个页面来获取限制条件和“如何”方面的信息。我花了很长时间才意识到我需要:
myView.translatesAutoresizingMaskIntoConstraints = NO;
才能使这个示例工作。感谢Userxxx、Rob M.和尤其是larsacus在这里的解释和代码,这对我非常宝贵。
这是完整的代码,使得上面的示例能够运行:
UIView *myView = [[UIView alloc] init]; myView.backgroundColor = [UIColor redColor]; myView.translatesAutoresizingMaskIntoConstraints = NO; //This part hung me up [self.view addSubview:myView]; //needed to make smaller for iPhone 4 dev here, so >=200 instead of 748 [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[myView(>=200)]-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(myView)]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[myView(==200)]-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(myView)]];
在代码中使用自动布局时,设置框架大小是无效的。因此,您上面指定的视图宽度为200不会对设置约束产生影响。为了使视图的约束集合没有歧义,需要四个元素:给定状态下的x位置、y位置、宽度和高度。
目前,上面的代码中只有两个元素(相对于父视图的高度和y位置)。除此之外,您还有两个必需的约束,这取决于如何设置视图父视图的约束。如果父视图有一个必需的约束,指定其高度小于748,则会出现“不可满足的约束”异常。
在设置约束之前设置视图的宽度是无效的。它甚至不会考虑旧框架,并将根据为这些视图指定的所有约束计算一个新的框架。在处理代码中的自动布局时,我通常只使用initWithFrame:CGRectZero
或简单的init
创建一个新视图。
要创建问题描述中所需的布局约束集合,需要添加一些水平约束来绑定宽度和x位置,以便给出完全指定的布局:
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[myView(>=748)]-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(myView)]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[myView(==200)]-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(myView)]];
口头上描述这个布局如下,从垂直约束开始:
myView将用标准间距填充其父视图的高度,并具有顶部和底部内边距。myView的父视图高度最小为748pts。myView的宽度为200pts,其对应父视图的标准间距为右内边距。
如果您只想让视图填充整个父视图的高度而不限制父视图的高度,则可以在视觉格式文本中省略(>=748)
参数。如果您认为(>=748)
参数是必需的以给视图指定高度,则在此情况下不是必需的:使用棒(|
)或带空格的棒(|-
,-|
)语法将视图固定在父视图的边缘上,你将给视图一个y位置(将视图固定在单边)和一个具有高度的y位置(将视图固定在两个边),从而满足视图的约束集合。
关于您的第二个问题:
使用NSDictionaryOfVariableBindings(self.myView)
(如果您已经设置了myView的属性)并将其馈入您的VFL以在VFL文本中使用self.myView
,当自动布局尝试解析您的VFL文本时,您可能会得到异常。这与字典键中的点符号以及系统尝试使用valueForKeyPath:
有关。点符号在字典键中不允许。详情请见此处类似问题和答案。