0

我有一个包含 UITextView 和 UIImageView 的 UITableViewCell。文本视图已禁用滚动。UITableViewCell 确实使用自动布局来计算其高度以适应内容。

查看布局截图

如果文本多于屏幕截图中的文本,我希望文本围绕图像流动并使用其下方的空间。因此我在文本视图上使用排除路径。排除路径设置正确,文本在图像周围流动。

必须在自动布局计算完框架后设置排除路径。由于排除路径阻塞了文本视图上的一些视图空间,因此包含的文本不再适合为文本视图计算的高度自动布局。

我怎样才能使它与自动布局一起工作?

设置排除路径后,我尝试在文本视图上设置高度约束:

    let size = textView.sizeThatFits(CGSize(width: textView.frame.size.width, height: CGFloat(MAXFLOAT)))
    textView.heightAnchor.constraint(equalToConstant: size.height).isActive = true

这无济于事。我需要调用layoutSubviews()UITableViewCell 来强制它重新计算它的高度。但是,当我将排除路径设置为viewDidLayoutSubviews().

4

2 回答 2

0

我发现它UITextView不会重新计算intrinsicContentSize何时isScrollEnabledfalsetextContainer.exclusionPaths变化。

解决方案很简单:

class FixedTextView : UITextView {
    
    func setExclusionPaths(_ paths: [UIBezierPath]) {
        textContainer.exclusionPaths = paths
        
        if !isScrollEnabled {
            invalidateIntrinsicContentSize()
        }
    }
}
于 2020-11-14T20:53:51.387 回答
-1

我有一个类似的问题,我无法在没有大量过度耦合的情况下访问 viewDidLayoutSubviews(),所以我感到你很痛苦。

假设您有视图 A 并且子视图包含一个 UITextView。

在视图 A 中,覆盖 layoutSubviews()

override public func layoutSubviews() {
  super.layoutSubviews()
  // At this point, UITextView is laid out and has a valid frame.
  // Set exclusion paths here, now that you have enough info to set coordinates.
  super.layoutSubviews() // do it again.
}

这类似于在以前的 iOS 版本中使用 UILabel 和 maxPreferredWidth 的方法。 iOS:自动布局中的多行 UILabel

一个警告:我不知道在此处设置约束会对您有所帮助,因为布局周期并不能真正以这种方式工作,但是根据Cell Subview 的此 Update Constraints,您可能可以摆脱 layoutIfNeeded ()。

于 2017-08-01T21:13:47.137 回答