无法使用自动布局“打开"移动 UILabel 的 Y 位置在视野中 [英] Can't move UILabel's Y position with Autolayout "on" in view

查看:10
本文介绍了无法使用自动布局“打开"移动 UILabel 的 Y 位置在视野中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须在这里遗漏一些非常明显的东西,但这是一个让我沮丧了好几天的问题.

I must be missing something terribly obvious here, but this has been an issue that's been frustrating me for DAYS.

在 xcode 4.5 上的 iOS 项目中,我在一个 XIB 中有几个标签,一个在另一个之上,在一个占据 UIViewUIScrollView 中.每个标签都与视图一样宽,每个标签都比下一个高 20 px.有时,其中一个标签没有任何信息,因此它被设置为不可见,并且它下面的标签应该向上移动以占据空白空间.

In an iOS project on xcode 4.5, I've got several labels in a XIB, one on top of the other, in a UIScrollView that occupies a UIView. Each label is as wide as the view, and each is about 20 px above the next. On occasion, one of the labels doesn't have any information, so it gets set to invisible, and the labels below it are supposed to move up to occupy the blank space.

问题是,如果在视图上选中关闭"自动布局,标签会完全按照应有的方式向上移动,尽管 UIScrollView 不再滚动.如果是on,则无论如何标签都不会移动.

The problem is, if autolayout is checked "off" on the view, the labels move up exactly as they should, though the UIScrollView no longer scrolls. If it is on, the labels do not move at all, no matter what.

这是代码...我基本上只是使用一个快速函数将每个标签向上移动不可见标签的高度.

Here is the code... I basically just use a quick function to move each label up by the height of the invisible label.

[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 已经移动,但它并没有在屏幕上移动.我确定它与垂直空间约束有关,但它不会让我删除约束,也不会让我将其更改为视图顶部空间以外的任何内容.就像我说的,我确定我错过了一些东西,但我已经用尽了我所知道的一切......

When it's run, the NSLog shows it's Y has moved, but it doesn't move on the screen. I'm sure it has to do with the vertical space constraint, but it won't let me delete the constraint, and it won't let me change it to anything other than space from the top of the view. Like I said, I'm sure I'm missing something, but I've exhausted everything I know to do...

推荐答案

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

If you have just one label that might be hidden, you can move the ones below it, up with the following:

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

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

The top label has a constraint to the top of the scroll view, and all the other labels have 20 point vertical distance constraints to the ones above and below them. In this example, I'm hiding label2. The labels are all 34 points high, so changing the constraint constant from 20 to -34 moves the now hidden label right on top of the one above it.

要对可以隐藏的多个标签使用此方法,您需要为每个要隐藏的标签设置一个出口,并限制其对上面的标签的约束.实际上,您可以在没有约束条件的情况下做到这一点,但我不知道它是否会那么健壮(它可能会选择错误的约束条件).我可以通过循环遍历约束来找到与特定标签一起使用的约束,并且是该标签顶部的约束:

To use this method with multiple labels that can be hidden, you will need to have an outlet to each of the labels you want to hide, and to its constraint to the label above. You actually can do it without outlets to the constraints, but I don't know if it would be as robust (it's possible that it might pick the wrong constraint). I was able to do the same thing by looping through the constraints to find the one that goes with a particular label, and is the one to the top of that label:

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

如果您愿意,可以修改相同的方法以使用动画 - 以下代码片段淡出您要隐藏的标签,同时为所有较低标签的上移设置动画.

The same method can be modified to use an animation if you like -- the following snippet fades out the label you want to hide while animating the move up of all the lower labels.

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

这篇关于无法使用自动布局“打开"移动 UILabel 的 Y 位置在视野中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆