【问题标题】:UITableViewCell - constraints only updated after reloadUITableViewCell - 约束仅在重新加载后更新
【发布时间】:2017-06-28 18:00:04
【问题描述】:

我有一个自定义 UITableViewCell,其中有一个包含多个子视图的 UIView。根据具体情况,我会隐藏其中的一些视图,并更新约束以使父 UIView 仍位于我的 UITableViewCell 的中心。

我的问题是,由于单元格重用,这仅在未直接显示单元格时才有效(如果单元格不是表格中首先出现的顶部单元格之一)。在这种情况下,当我向下滚动并向上滚动时,它会再次起作用。图片将帮助我解释这一点:

这是第一次加载 UITableView 时显示的内容。第一个单元格是包含所有信息的常规单元格,第二个单元格是隐藏第一个元素的单元格。

当我向下滚动然后再向上滚动时会发生这种情况。

如您所见,这正是我想要的。约束已正确更新,但只有在单元格从可见屏幕上消失并再次出现时才更新。

[reviewsAndPriceView setNeedsUpdateConstraints];
[reviewsAndPriceView setNeedsLayout];
[reviewsAndPriceView layoutIfNeeded];
[self updateConstraints];
[self setNeedsUpdateConstraints];
[self setNeedsLayout];
[self layoutIfNeeded];

还有各种变体,但都行不通。有什么方法可以做到这一点?

【问题讨论】:

    标签: ios objective-c uitableview nslayoutconstraint reusability


    【解决方案1】:

    我遇到了同样的问题。我通过在cellForRowAtIndexPath 中返回单元格之前调用cell.layoutIfNeeded() 解决了这个问题。现在,对我来说它工作正常。

    【讨论】:

      【解决方案2】:

      您已经知道 cells 正在被重复使用。

      当您滚动时,一些cells 正在使用之前显示的constraint

      要解决此call 问题,需要使用一种重置方法,该方法会将所有constraint 重置为其在xib 中指定的默认值。

      在这个方法之后调用你负责改变高度/宽度的方法。

      仅在最后一次通话中:

       [self layoutIfNeeded];
      

      【讨论】:

      • 那么我应该在哪里重置所有约束?在 cellForIndexPath 的最开始?我试过这样做,但它并没有改变任何东西。
      • 这似乎也没有解决它。因此,在生成单元格后,我应该将所有约束重置为其原始值,然后重新更改它们?奇怪的是,重置它们也不会改变任何东西。
      • @bloemy 你的细胞只被创建一次。如果一次可见单元格为 5 个,则仅创建 5 个单元格。当您滚动时,这些单元格将被重用。这些约束现在已更新。明白我的意思。
      • 我明白,但我的 TableViewCell 的初始化是在我的自定义类中进行的。 [tableView dequeueCellWith...] 调用是在另一个类中进行的,我的主类调用了我的自定义单元类。我不想在我的主课上做任何改变。有没有办法直接在我的子类中解决这个问题?
      • 你必须 [someview.superview layoutIfNeeded]layoutIfNeeded 设置为你已更改的视图的超级视图
      【解决方案3】:

      我使用 multiplier 设计了 ​​collectoin 视图单元。并且某些单元格部分无法在真实设备上正确显示。 使用下面的 3 种方法并在特定时间重新加载收藏夹视图,情节提要中设置的约束在真实设备上正确显示。

      (您可以在集合视图和表格视图中使用此解决方案)

      override func viewDidAppear(_ animated: Bool) {
      
              colLessons.reloadData()
              colLessons.setNeedsLayout()
              colLessons.layoutIfNeeded()
              colLessons.reloadData()
      
      }
      
      func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
      
              colLessons.reloadData()
              colLessons.setNeedsLayout()
              colLessons.layoutIfNeeded()
              colLessons.reloadData()
      
      }
      
      func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
      
              colLessons.reloadData()
              colLessons.setNeedsLayout()
              colLessons.layoutIfNeeded()
              colLessons.reloadData()
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-12-25
        • 2020-09-30
        • 2017-11-01
        • 2013-02-25
        • 2019-08-30
        • 1970-01-01
        • 2011-03-29
        相关资源
        最近更新 更多