无法将UILabel的Y位置与Autolayout“on”一起移动

在这里,我一定会错过一些非常明显的东西,但这一直是一个令我感到灰心的问题。

在xcode 4.5的iOS项目中,我在XIB中有一些标签,一个在另一个之上,在一个占用UIViewUIScrollView中。 每个标签都和视图一样宽,每个标签大约20px。 有时,其中一个标签没有任何信息,所以它被设置为不可见,下面的标签应该向上移动以占据空白区域。

问题是,如果在视图上将“自动布局”选中为“closures”,则尽pipeUIScrollView不再滚动,但标签仍按照原样移动。 如果打开 ,标签不会移动,不pipe怎样。

这里是代码…我基本上只是使用一个快速的function来移动每个标签的高度不可见的标签。

 [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显示它已经移动了,但是它不能在屏幕上移动。 我确定它与垂直空间约束有关,但它不会让我删除这个约束,它不会让我把它改变为除了视图顶部之外的空间。 就像我说的,我确定我错过了一些东西,但是我已经用尽了我所知道的一切…

如果只有一个可能被隐藏的标签,则可以将其移动到其下方,如下所示:

  -(void)contract { self.label2.hidden = YES; self.con2To1.constant = -34; } 

顶部标签对滚动视图的顶部有一个约束,而其他所有标签对它们上下的约束都有20点的垂直距离约束。 在这个例子中,我隐藏了label2。 标签都是34点高,因此将约束常数从20更改为-34会将现在隐藏的标签移到上面的标签上。

要使用具有多个隐藏标签的方法,您需要为每个要隐藏的标签设置一个出口,并将其限制到上面的标签。 你实际上可以做到这一点,没有网点的约束,但我不知道它是否会像健壮(可能会select错误的约束)。 我可以通过遍历约束来find与特定标签一致的东西,并且是该标签顶部的那个:

 -(void)hideLabel:(UILabel *) label { label.hidden = YES; for (NSLayoutConstraint *con in self.scroller.constraints) { if (con.firstItem == label && con.firstAttribute == NSLayoutAttributeTop) { con.constant = -34; } } } 

同样的方法可以修改为使用animation,如果你喜欢 – 下面的片段淡出你想隐藏的标签,同时animation所有较低的标签上移。

  -(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]; }]; } } } 

使用自动布局时,不能在子视图上设置框架 – 最好的情况是,它将暂时工作,直到下一个布局通过发生。 此时,您的约束定义的布局将被重新build立。

你必须做的是修改在视图上的约束。 在你的情况下,在每个标签上放置一个特定的引脚到高度约束是明智的。 然后,您可以创build出口到这些约束中的每一个。 对于一个零高度的标签,你可以将相关约束的常量设置为零。 下面的标签会上移。

根据您要删除的标签,这可能会给您带来双倍的差距。 你可以通过修改间隔约束来消除这个问题,或者你可以完全摆脱间距约束,只是每个标签都有一个高一点的距离,但是紧挨着对方 – 标签的内容将会垂直居中。

主要的信息是你不设置框架。 您可以修改,添加和/或删除约束。

如果你想迅速做到这一点:

 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() } } }