我必须在这里遗漏一些非常明显的东西,但这是一个让DAYS感到沮丧的问题。
在xcode 4.5上的iOS项目中,我在XIB中有多个标签,一个在另一个上面,在UIScrollView
中占据UIView
。每个标签都与视图一样宽,每个标签比下一个标签高约20 px。有时,其中一个标签没有任何信息,因此它被设置为不可见,并且它下面的标签应该向上移动以占据空白区域。
问题是,如果在视图上选中“关闭”自动布局,标签会尽可能地向上移动,尽管UIScrollView
不再滚动。如果 ,标签根本不会移动,无论如何。
这是代码......我基本上只是使用快速功能将每个标签向上移动不可见标签的高度。
[self moveObjectBy: self.festNameLabel moveByY:-(yearsLabel.frame.size.height-2)];
// this just quickly moves a label.
- (void)moveObjectBy:(UIView *)lbl moveByY:(int)byHeight {
CGRect newFrame = lbl.frame;
NSLog(@"%f, %d", newFrame.origin.y, byHeight);
newFrame.origin.y += byHeight; //yearsLabel.frame.size.height;
lbl.frame = newFrame;
}
当它运行时,NSLog
显示Y已移动,但它不会在屏幕上移动。我确定它与垂直空间约束有关,但它不会让我删除约束,它不会让我从视图顶部将其更改为空间以外的任何内容。就像我说的,我确定我错过了什么,但我已经筋疲力尽了我所知道的一切......
答案 0 :(得分:14)
如果您只有一个可能隐藏的标签,您可以移动它下方的标签,以下内容:
-(void)contract {
self.label2.hidden = YES;
self.con2To1.constant = -34;
}
顶部标签对滚动视图的顶部有一个约束,而所有其他标签对它们上面和下面的标签都有20点垂直距离约束。在这个例子中,我隐藏了label2。标签全部高34点,因此将约束常数从20更改为-34会将现在隐藏的标签移动到其上方的标签顶部。
要将此方法与可隐藏的多个标签一起使用,您需要为要隐藏的每个标签设置一个插座,并对其上面的标签进行约束。你实际上可以在没有出口约束的情况下做到这一点,但我不知道它是否会如此强大(它可能会选择错误的约束)。通过循环约束来找到与特定标签一起使用的约束,并且是该标签顶部的那个,我能够做同样的事情:
-(void)hideLabel:(UILabel *) label {
label.hidden = YES;
for (NSLayoutConstraint *con in self.scroller.constraints) {
if (con.firstItem == label && con.firstAttribute == NSLayoutAttributeTop) {
con.constant = -34;
}
}
}
如果您愿意,可以修改相同的方法以使用动画 - 以下片段淡化您要隐藏的标签,同时为所有下标签的移动设置动画。
-(void)hideLabel:(UILabel *) label {
for (NSLayoutConstraint *con in self.scroller.constraints) {
if (con.firstItem == label && con.firstAttribute == NSLayoutAttributeTop) {
con.constant = -34;
[UIView animateWithDuration:.5 animations:^{
label.alpha = 0;
[self.scroller layoutIfNeeded];
}];
}
}
}
答案 1 :(得分:5)
使用自动布局后,您无法在子视图上设置框架 - 充其量,它将暂时有效,直到发生下一个布局过程。此时,将重新建立由约束定义的布局。
您需要做的是修改视图上的约束。在您的情况下,在每个标签上具有特定的引脚到高度约束是明智的。然后,您可以为每个约束创建出口。对于零高度标签,您可以将相关约束上的常量设置为零。然后下面的标签会向上移动。
根据您要移除的标签,这可能会给您留下双倍宽的间隙。您可以通过修改间距约束来删除它,或者您可以完全摆脱间距约束,只是让每个标签更高一点,但是彼此相邻 - 标签的内容无论如何都将垂直居中。
主要信息是您没有设置框架。您可以修改,添加和/或删除约束。
答案 2 :(得分:0)
for item in self.view.constraints
{
if item.firstItem .isKindOfClass(UITextField)
{
let newField = item.firstItem as! UITextField
if newField == answerTextField && item.firstAttribute == NSLayoutAttribute.Top
{
item.constant = answerFrame.origin.y
self.view .layoutIfNeeded()
}
}
if item.firstItem .isKindOfClass(UIButton)
{
let newField = item.firstItem as! UIButton
if newField == submitButton && item.firstAttribute == NSLayoutAttribute.Top
{
item.constant = submitFrame.origin.y
self.view .layoutIfNeeded()
}
}
}