4

我正在尝试将 UIButton 放置在 UITextView 中一大块动态生成的文本中的特定点。然而,事实证明,及时获得准确的坐标非常困难。已使用预生成的 NSAttributedString 设置了属性文本,现在,我将按钮添加到 NSLayoutManager 的委托方法中,因为这似乎是最合乎逻辑的地方。但是,我对其他选择持开放态度!

以下是相关代码:

func layoutManager(layoutManager: NSLayoutManager, didCompleteLayoutForTextContainer textContainer: NSTextContainer?, atEnd layoutFinishedFlag: Bool) {

        let layoutManager = textView.layoutManager
        let textContainer = textView.textContainer
        let text = textView.attributedText
        let inset = textView.textContainerInset.top

        text.enumerateAttribute(NSAttachmentAttributeName, inRange: NSMakeRange(0, text.length), options: .LongestEffectiveRangeNotRequired) { (value, range, stop) in
            if (value != nil) {
                let boundingRect = layoutManager.boundingRectForGlyphRange(range, inTextContainer: textContainer)
                let frame = CGRectMake(boundingRect.origin.x, boundingRect.origin.y+inset, boundingRect.size.width, boundingRect.size.height)
                let button = UIButton()
                button.setImage(UIImage(named: "canterbury_small_dark.png"), forState: .Normal)
                self.textView.addSubview(button)
                button.frame = frame
        }
    }
}

这段代码很好用,但只有当你一直滚动到 UITextView 的底部时才会触发它。有没有办法确保对整个文本执行了所有布局,而不必一直滚动到视图底部?我在 NSLayoutManager 中尝试了许多方法,这些方法说它们“如果需要,执行字形生成和布局”,例如 glyphRangeForTextContainer()、ensureLayoutForCharacterRange() 等,但它们似乎没有满足我的需要。

我还尝试在代码中的其他位置添加按钮,例如在 viewWillAppear() 和 viewDidLoad() 中。但是,当我在这里尝试时,即使我调用了强制布局方法,当我调用 boundingRectForGlyphRange() 时,它也会返回 NSTextAttachment 图像的坐标,该坐标与图像在 textView 中实际结束的位置不准确,因此按钮最终出现在一个非常不准确的位置。

我毫不怀疑我错过了文本布局如何发生的重要内容,但我不知道它是什么。任何帮助将不胜感激!

4

0 回答 0