带有 NSLayoutConstraints 的 UIView 灵活高度
Posted
技术标签:
【中文标题】带有 NSLayoutConstraints 的 UIView 灵活高度【英文标题】:UIView flexible height with NSLayoutConstraints 【发布时间】:2015-10-28 16:40:00 【问题描述】:我在代码中向我的UIViewController
添加了一些视图,并使用NSLayoutConstraints
将它们定位在我希望它们在屏幕上的位置。在代码中对 NSLayoutConstraints 有点陌生;我做了一个测试设置,并且已经完成了 95%。这是我当前的代码:
UIView *redView = [[UIView alloc] init];
redView.backgroundColor = [UIColor redColor];
redView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:redView];
[redView addConstraint:[NSLayoutConstraint constraintWithItem:redView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil attribute:0
multiplier:1
constant:100]];
[redView addConstraint:[NSLayoutConstraint constraintWithItem:redView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:0
multiplier:1
constant:693]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:redView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeTop
multiplier:1
constant:60]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:redView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0]];
UIView *blueView = [[UIView alloc] init];
blueView.backgroundColor = [UIColor blueColor];
blueView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:blueView];
[blueView addConstraint:[NSLayoutConstraint constraintWithItem:blueView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:0
multiplier:10
constant:50]];
[blueView addConstraint:[NSLayoutConstraint constraintWithItem:blueView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil attribute:0
multiplier:1
constant:693]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:blueView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:redView attribute:NSLayoutAttributeBottom
multiplier:1 constant:70]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:blueView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:redView
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0]];
UIView *orangeView = [[UIView alloc] init];
orangeView.backgroundColor = [UIColor orangeColor];
orangeView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:orangeView];
[orangeView addConstraint:[NSLayoutConstraint constraintWithItem:orangeView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:0
multiplier:1
constant:25]];
[orangeView addConstraint:[NSLayoutConstraint constraintWithItem:orangeView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:0
multiplier:1
constant:693]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:orangeView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:blueView
attribute:NSLayoutAttributeBottom
multiplier:1
constant:25]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:orangeView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:blueView
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0]];
看起来像这样 - 正如我想要的那样:(忽略灰色背景 - 那是 superView)
现在我要做的是让orangeView
s 的高度将屏幕的其余部分填充到superView
的底部。但是,当我向 orangeView 添加底部约束时,它也会调整其他视图的高度。
如何获得橙色视图高度以填充其下方的灰色区域?
编辑:
移除orangeView
上的高度约束并像这样向超级视图添加底部约束:
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:orangeView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeBottom
multiplier:1
constant:0]];
像这样改变视图:
【问题讨论】:
在将底部添加到超级视图约束时是否删除了橙色视图的高度约束? @Leonardo 是的,我试过了;查看我更新的问题,了解当我这样做时会发生什么。谢谢! 【参考方案1】:您在橙色视图上设置了固定高度,那么它如何扩展并填充整个视图?
另外我建议您将视图的顶部固定到前一个视图的底部,因为您可以轻松更改视图大小并保持间距均匀,否则您将不得不调整底部的常量到底部的关系。
这是一个运行良好的代码:
UIView *redView = [[UIView alloc] init];
redView.backgroundColor = [UIColor redColor];
redView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:redView];
[redView addConstraint:[NSLayoutConstraint constraintWithItem:redView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:0
multiplier:1
constant:100]];
[redView addConstraint:[NSLayoutConstraint constraintWithItem:redView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:0
multiplier:1
constant:693]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:redView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeTop
multiplier:1
constant:60]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:redView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0]];
UIView *blueView = [[UIView alloc] init];
blueView.backgroundColor = [UIColor blueColor];
blueView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:blueView];
[blueView addConstraint:[NSLayoutConstraint constraintWithItem:blueView
attribute:NSLayoutAttributeHeight
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:0
multiplier:1
constant:50]];
[blueView addConstraint:[NSLayoutConstraint constraintWithItem:blueView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil attribute:0
multiplier:1
constant:693]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:blueView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:redView attribute:NSLayoutAttributeBottom
multiplier:1 constant:10]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:blueView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:redView
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0]];
UIView *orangeView = [[UIView alloc] init];
orangeView.backgroundColor = [UIColor orangeColor];
orangeView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:orangeView];
[orangeView addConstraint:[NSLayoutConstraint constraintWithItem:orangeView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:0
multiplier:1
constant:693]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:orangeView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:blueView
attribute:NSLayoutAttributeBottom
multiplier:1
constant:25]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:orangeView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeBottom
multiplier:1
constant:0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:orangeView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:blueView
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0]];
【讨论】:
这正是我所追求的。我最初试图将下一个视图固定在前一个视图的底部,除了我使用底部/底部关系而不是顶部/底部 - 没有完全理解代码。但现在我愿意。谢谢!【参考方案2】:您需要将Y constraints
设置为橙色视图:为蓝色视图设置bottomLayout 约束和垂直间距。如果 XCode 用橙色警告警告您,请阅读这些警告,它通常会说“您的视图需要 X 约束”。
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:|-[yourViewHere(300)]-50-|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(yourViewHere)]];
(300)
是视图的宽度。该代码剪辑器将约束从 bottomLayout 设置为您的视图。如上所述添加类似的约束。
【讨论】:
以上是关于带有 NSLayoutConstraints 的 UIView 灵活高度的主要内容,如果未能解决你的问题,请参考以下文章
使用 NSLayoutConstraints 调整当前视图的大小
在 UITableView 的标题视图上使用 NSLayoutConstraints
NSLayoutConstraints 的 UIViewPropertyAnimator 使视图消失
Swift 中的尾随和前导约束以编程方式 (NSLayoutConstraints)