iOS提取文本中鏈接添加高亮點(diǎn)擊,String NSString 對于表情NSRange計(jì)算長度不同,YYTextHighlight手勢沖突問題

直接上代碼,通過以下計(jì)算就可以完成鏈接的識別以及替換,然后添加高亮以及對高亮文字添加點(diǎn)擊事件

let label = YYLabel()
        label.backgroundColor = .red
        label.numberOfLines = 0
        label.preferredMaxLayoutWidth = 200
        view.addSubview(label)
        label.snp.makeConstraints { (make) in
            make.left.equalTo(50)
            make.width.equalTo(200)
            make.top.equalTo(300)
        }
        
        var urls: [String] = []
        
        var string = "test\\n\ntest/\\n\n??\nhttps://mbd.baidu.com/newspage/data/landingsuper?context=%7B%22nid%22%3A%22news_9827769369551786176%22%7D&n_type=0&p_from=1 第二個 https://weibo.com/mygroups?gid=201209041125312675&wvr=6&leftnav=1&isspecialgroup=1 今天又是好天氣!今天又是好天氣!今天又是好天氣!今天又是好天氣!今天又是好天氣!";
        
//        var string = "est\\n\ntest/\\n\n??\nhttps://www.weibo.com/beat/beatslist/beat?keyword=測試 https://weibo.com/mygroups?gid=201209041125312675&wvr=6&leftnav=1&isspecialgroup=1 每天都很美好";

        let detector = try? NSDataDetector.init(types: NSTextCheckingResult.CheckingType.link.rawValue)
        let matches = detector?.matches(in: string, options: [.reportProgress], range: NSRange(location: 0, length: string.count))
        for match in matches! {
            if match.resultType == .link {
                if let url = match.url {
                    //這里獲取到的url是經(jīng)過encode處理的
                    urls.append(url.absoluteString)
                }
            }
        }
        
        print("encode urls \(urls)")
        
        let font = UIFont.systemFont(ofSize: 15)
        let attribbutes = NSMutableAttributedString(string: "")
        for str in urls {
           
            var strArray = string.components(separatedBy: str)
            if strArray.count < 2 {
                //如果沒有匹配到字符說明string沒有經(jīng)過encode,但是str為encode以后的字符,所以需要decode str才能識別
                if let decode = str.removingPercentEncoding {
                    strArray = string.components(separatedBy: decode)
                }
            }
            if let firstStr = strArray.first {
                let subAttribute = NSMutableAttributedString(string: firstStr)
                subAttribute.setColor(.cyan, range: NSRange(location: 0, length: firstStr.count))
                attribbutes.append(subAttribute)
                
                let hightText = YYTextHighlight()
                hightText.tapAction = { view, text, range, rect in
                    guard let url = URL(string: str) else {
                        print("error url \(str)")
                        return
                    }
                    print("open url \(url)")
                    UIApplication.shared.open(url, options: [:], completionHandler: nil)
                }
                
                let imageAttribute = NSMutableAttributedString.attachmentString(withContent: UIImage(named: "commend_kink"), contentMode: .scaleAspectFit, attachmentSize: .init(width: 18, height: 18), alignTo: font, alignment: .center)
                let replaceStr = NSMutableAttributedString(string: "查看鏈接")
                replaceStr.setColor(.yellow, range: NSRange(location: 0, length: 4))
                imageAttribute.append(replaceStr)
                imageAttribute.setTextHighlight(hightText, range: NSRange(location: 0, length: 5))
                attribbutes.append(imageAttribute)
            }
            
            if let lastStr = strArray.last {
                string = lastStr
            }
            
        }
        let lastAttribute = NSMutableAttributedString(string: string)
        lastAttribute.setColor(.cyan, range: NSRange(location: 0, length: string.count))
        attribbutes.append(lastAttribute)
        
        label.attributedText = attribbutes
注意點(diǎn)YYLabel UILabel用法差異

使用YYLabel和使用UILabel還是有一些區(qū)別的。如果使用UILabel設(shè)置了lable的font、textColor,在給label的text賦值或者attributedText賦值時,上述設(shè)置都會生效。但是YYLabel設(shè)置font、textColor只會對label的text生效,對于attributedText屬性必須對NSAttributedString、NSMutableAttributedString進(jìn)行設(shè)置。

YYLabel高度自適應(yīng) preferredMaxLayoutWidth

對于UIlabel僅設(shè)置label.numberOfLines = 0,并且不設(shè)置高度lable就會隨著顯示內(nèi)容自動增長,但是對于YYLable除了設(shè)置label.numberOfLines = 0,還要設(shè)置label.preferredMaxLayoutWidth,只有這樣YYLabel才會自增長。

String NSString 對于表情NSRange計(jì)算長度不同

由下圖可以看出對于純文字不管是String類型NSString計(jì)算結(jié)果都一樣。但是對于含有表情的文本計(jì)算,兩者計(jì)算結(jié)果不一樣。對于這種情況可以使用NSString計(jì)算也可以使用String調(diào)用.utf16.coun計(jì)算。NSString默認(rèn)使用utf16計(jì)算,而表情大部分也需要使用utf16計(jì)算,所以直接使用NSString就可以得到正確的結(jié)果。

 let range = NSMakeRange(0, string.count)
 let nsStr = string as NSString
 let conTentRange = NSMakeRange(0, nsStr.length)
 //let conTentRange = NSMakeRange(0, string.utf16.count)
 printf("range \(range) conTentRange \(conTentRange)  text \(text)")
image
YYTextHighlight和父視圖手勢會沖突問題
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        //YYTextHighlight和父視圖手勢會沖突,所以需要識別點(diǎn)擊位置是否包含YYTextHighlight
        if touch.view is YYLabel {
            let label = touch.view as? YYLabel
            if let label = label {
                var range = NSMakeRange(0, 1);
                let highlight = label._getHighlight(at: touch.location(in: label), range: &range)
                if highlight != nil {
                    return false
                }
            }
        }
        return true
    }

上邊代碼中-(YYTextHighlight *)_getHighlightAtPoint:(CGPoint)point range:(NSRangePointer)range;為私有方法,外部不可調(diào)用,又考慮到引用的是別人的第三方庫,所以需要創(chuàng)建一個YYLabel的分來,然后將此方法在YYLabel分類的.h中聲明。如下:

#import "YYLabel.h"

NS_ASSUME_NONNULL_BEGIN

@interface YYLabel (YHYYLabel)

- (YYTextHighlight *)_getHighlightAtPoint:(CGPoint)point range:(NSRangePointer)range;

@end

NS_ASSUME_NONNULL_END

本人原文博客地址

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 為什么要做這個筆記 masonry [https://github.com/SnapKit/Masonry]可以說...
    blackie_james閱讀 832評論 0 0
  • 利用NSAttributedString (富文本)能調(diào)整UILable等文字相關(guān)控件顯示文字的字體、顏色、字體間...
    Sweet丶閱讀 2,538評論 0 0
  • Auto Layout 是怎么進(jìn)行自動布局的,性能如何? Auto Layout 到底是如何實(shí)現(xiàn)自動布局的,這種布...
    為了自由的白菜閱讀 391評論 0 0
  • 16宿命:用概率思維提高你的勝算 以前的我是風(fēng)險厭惡者,不喜歡去冒險,但是人生放棄了冒險,也就放棄了無數(shù)的可能。 ...
    yichen大刀閱讀 7,922評論 0 4
  • 公元:2019年11月28日19時42分農(nóng)歷:二零一九年 十一月 初三日 戌時干支:己亥乙亥己巳甲戌當(dāng)月節(jié)氣:立冬...
    石放閱讀 7,472評論 0 2

友情鏈接更多精彩內(nèi)容