我正在尝试将UIButton放置在UITextView中,在一大块动态生成的文本中的特定点。然而,事实证明,及时获得准确的坐标非常困难。 attributesText已经使用预先生成的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中结束的位置,所以按钮最终位于一个非常不准确的位置。
我毫不怀疑我错过了关于文本布局如何发生的重要事情,但我对此感到茫然。任何帮助都将深表感谢!