我一直在调查在UILabel中找到hashtags / mentions / ...的方法 那里的所有Libs都做得很好但是当谈到RTL语言如persian和文本在UITableView中变得太长时,滚动变得滞后并且每次访问此行时消耗CPU高达50%,我发现所有这些库都是以某种方式使用textStorage,并通过删除它和使用缓存方法,滞后全部消失,列表滚动顺利,但问题是没有textStorage它不可能(我找不到方法)找到被触摸的字符用户。所以,如果我解决这个问题,我的RTL语言问题就解决了,所以问题是:我们有一个UIlabel和一个CGPoint如何找到触及的字符?
目前使用ContextLabel Library的这种修改方法:
fileprivate func linkResult(at location: CGPoint) -> LinkResult? {
var fractionOfDistance: CGFloat = 0.0
let characterIndex = layoutManager.characterIndex(for: location, in: textContainer, fractionOfDistanceBetweenInsertionPoints: &fractionOfDistance)
if characterIndex <= textStorage?.length {
if let linkResults = contextLabelData?.linkResults {
for linkResult in linkResults {
let rangeLocation = linkResult.range.location
let rangeLength = linkResult.range.length
let rect = self.boundingRect(forCharacterRange: linkResult.range)
if(rect?.contains(location))!
{
return linkResult
}
}
}
}
return nil
}
boundingRect是
func boundingRect(forCharacterRange range: NSRange) -> CGRect? {
guard let attributedText = attributedText else { return nil }
let textStorage = NSTextStorage(attributedString: attributedText)
let layoutManager = NSLayoutManager()
textStorage.addLayoutManager(layoutManager)
let textContainer = NSTextContainer(size:CGSize(width:self.bounds.size.width, height: CGFloat.greatestFiniteMagnitude))
textContainer.lineFragmentPadding = 0.0
layoutManager.addTextContainer(textContainer)
var glyphRange = NSRange()
// Convert the range for glyphs.
layoutManager.characterRange(forGlyphRange: range, actualGlyphRange: &glyphRange)
return layoutManager.boundingRect(forGlyphRange: glyphRange, in: textContainer)
}
和linkResults是之前找到的那些hashtags,mentions,url ...现在要搜索它们,当textStorage被删除时,它总是返回nil
更新:它现在使用当前的英文文本方法,无论多长时间但不适用于RTL