【问题标题】:UITextView auto layout height when using exclusion path使用排除路径时的 UITextView 自动布局高度
【发布时间】:2017-11-17 03:52:31
【问题描述】:

我有一个包含 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

这没有帮助。我需要在 UITableViewCell 上调用layoutSubviews() 以强制它重新计算其高度。但是,当我在viewDidLayoutSubviews() 中设置我的排除路径时,这将创建一个无限循环。

【问题讨论】:

  • UIView 有一个特殊的功能可以更新约束。也许尝试像这样覆盖它:override func updateConstraints() { super.updateConstraints() let size = textView.sizeThatFits(CGSize(width: textView.frame.size.width, height: CGFloat(MAXFLOAT))) textView.heightAnchor.constraint(equalToConstant: size.height).isActive = true }

标签: ios uitextview nslayoutconstraint ios-autolayout exclusionpath


【解决方案1】:

我发现当isScrollEnabledfalsetextContainer.exclusionPaths 发生变化时,UITextView 不会重新计算intrinsicContentSize

解决方法很简单:

class FixedTextView : UITextView {
    
    func setExclusionPaths(_ paths: [UIBezierPath]) {
        textContainer.exclusionPaths = paths
        
        if !isScrollEnabled {
            invalidateIntrinsicContentSize()
        }
    }
}

【讨论】:

    【解决方案2】:

    我有一个类似的问题,我无法在没有大量过度耦合的情况下访问 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: Multi-line UILabel in Auto Layout

    一个警告:我不知道在这里设置一个约束会对你有帮助,因为布局周期并不是真的那样工作,但根据这个 Update Constraints of Cell Subview ,你也许可以侥幸逃脱layoutIfNeeded().

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-11
    • 2019-02-27
    • 2015-01-19
    • 1970-01-01
    • 2013-12-20
    • 2014-01-06
    • 2014-05-25
    • 1970-01-01
    相关资源
    最近更新 更多