4

我正在尝试做这样的事情:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    NSLog(@"%@", self.tableViewHeight);
    self.tableViewHeight.constant = 0;
    NSLog(@"%@", self.tableViewHeight);

    [self.tableView setNeedsUpdateConstraints];
    [self.tableView setNeedsLayout];
    [self.view setNeedsUpdateConstraints];
    [self.view setNeedsLayout];
}

但有时这行得通,有时不行。我总是在日志中看到正确的消息:

<NSLayoutConstraint:0x9ebe7a0 V:[UITableView:0xa345a00(304@500)] priority:500>
<NSLayoutConstraint:0x9ebe7a0 V:[UITableView:0xa345a00(0@500)] priority:500>

为什么会发生这种情况?如何在 UI 可见之前更改 NSLayoutConstraints 属性?

更新:

这段代码工作了 20 次的 20 次(但我现在总是这样认为):

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    dispatch_async(dispatch_get_main_queue(), ^{
        self.tableViewHeight.constant = 0;
        [self.view setNeedsUpdateConstraints];
    });
}

告诉我为什么会发生这种情况?

更新 2:

看起来以前的代码仍然无法正常工作,但这有效:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    self.topViewHeight.constant += self.tableViewHeight.constant;
    self.tableViewHeight.constant = 0;
    [self.view setNeedsUpdateConstraints];
}

更新 3:

我永远不会为连接视图的几个约束设置同等的优先级(如 500)......

4

1 回答 1

1

我注意到您的优先级为 500,这意味着您愿意打破此约束以满足其他约束。我想知道您还有哪些其他限制。如果在 Interface Builder 中执行此操作,它有一种烦人的倾向(至少在 Xcode 4.6.x 中)添加它认为需要的任何约束以消除歧义。您可能想要检查您是否没有其他高度约束或优先的顶部和底部约束。

最重要的是,您设置的技术constant很好(认为,我发现只需使用setNeedsLayout就足够了),问题可能在于可能挥之不去的其他约束。

如果您将此约束的优先级更改为 1000,如果您有冲突的约束,您将收到关于它们是什么的错误,这有助于诊断问题。但实际上,您是在告诉自动布局,如果忽略此高度约束以支持其他冲突约束(具有更高或同等优先级),则可以。通过将优先级设置为 1000,您就是说您永远不希望忽略此约束。

于 2013-06-28T17:52:23.780 回答