使用attributedString在UILabel中查找触摸的字符,而不使用TextStorage

时间:2018-06-14 07:27:58

标签: swift uilabel

我一直在调查在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

0 个答案:

没有答案