NSLayoutConstraints 在第一次 tableview 演示后更新

Posted

技术标签:

【中文标题】NSLayoutConstraints 在第一次 tableview 演示后更新【英文标题】:NSLayoutConstraints update after first tableview presentation 【发布时间】:2014-09-13 06:54:36 【问题描述】:
    我从 xib 加载自定义 UITableViewCell 我以编程方式更新NSLayoutConstraint cellForRowAtIndexPath

NSLayoutConstraint 的自动布局和手动更改可以正常工作 - 设备大小、方向等。

但是:在单元格的第一次演示中,程序更改不会显示。 按预期更改视图并返回更新。

我认为我需要将[self setNeedsUpdateConstraints] 放在某个地方。 各种地方都试过了(viewDidAppear, didEndDisplayingCell ...)

这应该去哪里?

可能是新电池/重复使用的电池问题?

【问题讨论】:

【参考方案1】:

所以,总结一下 - 这就是我所做的,以便每次都能获得布局合理的视图:

现在 UIView 自己负责,不用在 tableviewController 中乱搞。

我不需要在任何有意义的地方调用 (void)updateConstraints,因为我在 IB 中设置了约束并且只是添加了一个能够更改常量的属性。实际的约束保持不变,只需要布局!

    将所有布局代码移至我的 UITableViewCell 子类,将其命名为 (void)updateMedian(仅两行代码)。 创建了一个属性,用于将重新计算标签位置所需的信息(基本浮点数)传递到子类中。 在 UITableViewCell 子类的 (void)layoutSubviews 中使用 (void)updateMedian 来更新我的坐标。 还在我的子类的 (void)prepareForReuse 中添加了对 (void)updateMedian 和 [self layoutIfNeeded] 的调用。 添加了[cell setNeedsLayout];我的 tableviewController 中的 cellForRowAtIndexPath 中的 [cell layoutIfNeeded]。

我猜,最后一步有点多余。但除此之外,仍有一些单元格显示不正确。

【讨论】:

【参考方案2】:

您已经更新(修改)了一个约束,因此视图不需要更新其约束。它需要的是更新其布局以响应约束更改。所以,我认为你需要做[view setNeedsLayout]。应该在添加了约束的视图(或修改的约束中涉及的所有视图的共同祖先视图)上完成。应该在修改约束之后的相同代码中完成。

也就是说,我不确定-tableView:cellForRowAtIndexPath: 是否适合尝试修改返回视图的约束。此时,单元格视图尚未添加为表格的子视图。只能为同一视图层次结构中的视图添加约束。

【讨论】:

你说得对,我将约束修改移动到视图本身(见下面的评论)并解决了问题......【参考方案3】:

子类UITableViewCell 并在awakeFromNib: 中调用setNeedsLayout

您还可以将更新约束移至单元格的 updateConstraints 方法,使您的 UITableViewController 更小一些。毕竟,一个单元格是一个单独的UIView,它应该知道如何布局自己,而不是表格视图控制器。

【讨论】:

我已经继承了 UITableViewCell。您将代码移动到实际视图的建议非常有意义。这样做时我发现了实际问题:我的约束计算取决于标签的 frame.width。标签的文本在 cellForRowAtIndexPath 中设置。 所以,会发生以下情况:1) 新单元格:updateConstraints 被调用 - 错误的 label.width 2) 单元格重用:prepareForReuse - 正确的 label.width。将尝试更多并报告!【参考方案4】:

从你的问题我得到的是什么

如果您可以使用 pin 从情节提要中为对象提供约束,那么它将为对象设置这些约束,并且如果您在“cellForRowAtIndexPath:”中以编程方式添加约束,它将覆盖您在故事中设置的约束木板。您可能错误地将它们仅设置为单个单元格,因此它可能会在单个单元格中显示效果。

您能否尝试以下解决方案并检查它是否对您有帮助。将此代码放在 cellForRow 方法中。

我已经实现了

NSDictionary *viewsDictionary = @@"redView":cell.lblText;
    NSArray *constraint_H = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[redView(10)]"
                                                                    options:0
                                                                    metrics:nil
                                                                      views:viewsDictionary];

    NSArray *constraint_V = [NSLayoutConstraint constraintsWithVisualFormat:@"H:[redView(100)]"
                                                                    options:0
                                                                   metrics:nil
                                                                   views:viewsDictionary];

    [cell addConstraints:constraint_H];
    [cell addConstraints:constraint_V];

在 cellForRowAtIndexPath 中:

它影响了单元格中的所有行,并且它覆盖了约束。

您也可以访问此链接以获取更多参考: http://technet.weblineindia.com/mobile/ui-design-of-ios-apps-with-autolayout-using-constraints-programmatically/ http://www.thinkandbuild.it/learn-to-love-auto-layout-programmatically/

【讨论】:

我实际上为约束创建了一个 IBOUTLET 属性,因此不应该有冲突。

以上是关于NSLayoutConstraints 在第一次 tableview 演示后更新的主要内容,如果未能解决你的问题,请参考以下文章

带有 NSLayoutConstraints 的 UIView 灵活高度

在 UITableView 的标题视图上使用 NSLayoutConstraints

在 Swift 中枚举视图的 NSLayoutConstraints?

我在这个 NSLayoutConstraints 看不到错误

使用 NSLayoutConstraints 调整当前视图的大小

使用 NSLayoutConstraints 在 UIView 上简单滑动动画