如果我理解您的要求正确,我认为您只需要为每个子视图设置 2 个高度限制。
第一个将是一个高度约束,在显示父视图时,您希望高度为常数,并将优先级设置为小于 1000(我一直使用 800,它似乎适用于我想要的是)。这是当 superview 的高度不为 0 时将应用的约束。
第二个高度约束的 constant >= 0,priority 为 1000。这将是在超级视图高度 = 0 时应用的约束。
编辑:要获得优先级 800 约束的视图高度,您可以:
故事板:
使用您想要的任何内容设置视图。所以对于标签,设置行数、字体大小等,输入一些文本(它不一定是用户将看到的文本 - 你的代码可能会在某处改变myLabel.text。之后标签设置完毕,点击窗口右下角的“Pin”约束按钮,高度应该会自动填充。应用约束,然后在创建约束后编辑约束以降低优先级。
代码:
设置标签的字体、行数和其他一切,就像在故事板方法中一样,然后再次添加一些虚拟文本。然后,您可以通过调用[myLabel sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)].height 来询问标签要显示您给它的虚拟文本的高度
编辑 2:
好的,这和我以前的有点不同。让我们尝试一些屏幕截图和代码片段。这些只是来自我整理的一个快速测试项目,但您应该能够将这个想法扩展到您正在从事的工作。
在情节提要中,为您的超级视图(绿色背景)和超级视图顶部的位置设置水平约束。
然后,为展开高度添加高度约束。将此约束的优先级设置为High (750)。
然后,将您的子视图添加到父视图。为子视图添加约束,就好像一切正常,超级视图不会发生任何事情。唯一的区别是你想默认将.hidden 设置为YES (否则如果视图开始折叠,子视图将可见并且间距会很时髦)。请注意,对于多行标签,我没有指定高度限制 - XCode 会根据我输入的文本自行确定。
最后,为超级视图添加第二个高度约束,constant = 0,优先级为 1000。
现在是一点代码:
在视图控制器的 .h 文件中,为超级视图和视图的 height = 0 约束设置 IBOutlets。
MyViewController.h
#import <UIKit/UIKit.h>
@interface MyViewController : UIViewController
{
IBOutlet NSLayoutConstraint *superHeighConstraint;
IBOutlet UIView *myCollapsibleView;
}
@end
为了测试,我添加了一个 UISegmentedControl,它会在超级视图是否折叠时进行切换。下面是响应选择变化的代码:
MyViewController.m
...
- (IBAction)segmentUpdated:(UISegmentedControl *)sender
{
if ([sender selectedSegmentIndex] == 0)
{
[myCollapsibleView removeConstraint:superHeighConstraint];
for (UIView *subview in [myCollapsibleView subviews])
{
[subview setHidden:NO];
}
}
else if ([sender selectedSegmentIndex] == 1)
{
[myCollapsibleView addConstraint:superHeighConstraint];
for (UIView *subview in [myCollapsibleView subviews])
{
[subview setHidden:YES];
}
}
}
使用此设置,您永远不会更改代码中的任何约束 - 您只需选择何时应用或不应用父视图的 height = 0 约束。循环通过[myCollapsibleView subviews] 可以很容易地根据需要显示/隐藏子视图,并且它是动态完成的,因此如果您稍后添加或删除子视图,您不必接触代码。
模拟器图片:
加载:
切换显示:
切换隐藏: