最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

iOS?UITextView?實(shí)現(xiàn)類似微博的話題、提及用戶效果

 更新時(shí)間:2022年06月07日 11:27:07   作者:XboxYan  
這篇文章主要介紹了iOS?UITextView?實(shí)現(xiàn)類似微博的話題、提及功能,基本思路是使用正則匹配出成對(duì)的#,再利用UITextView的富文本實(shí)現(xiàn)高亮效果,需要的朋友可以參考下

最近接了一個(gè)需求,在發(fā)布動(dòng)態(tài)的時(shí)候,增加類似微博的#話題#、@提及用戶的效果,在此做一簡(jiǎn)要記錄。

#話題#

最終效果是:

  • 編輯過(guò)程中#話題內(nèi)容#實(shí)時(shí)高亮

  • 高亮部分可以響應(yīng)點(diǎn)擊事件

1.高亮

基本思路是:使用正則匹配出成對(duì)的#,再利用UITextView的富文本實(shí)現(xiàn)高亮效果。

func refreshTopicStyle() {
        
        let regex = try! NSRegularExpression(pattern: "此處填寫正則表達(dá)式",
                                             options:[NSRegularExpression.Options.caseInsensitive])
        // 注意點(diǎn)
        let totalRange = NSMakeRange(0, (inputTextView.attributedText.string as NSString).length)
        let results = regex.matches(in: inputTextView.attributedText.string,
                                    options: NSRegularExpression.MatchingOptions.init(rawValue: 0),
                                    range: totalRange)
        let attributedString: NSMutableAttributedString = NSMutableAttributedString(string: inputTextView.attributedText.string)
        attributedString.setAttributes(normalAttributes, range: totalRange)
        
        for result in results {
            attributedString.setAttributes(topicAttributes, range: result.range)
        }
        inputTextView.attributedText = attributedString
    }

這有一個(gè)注意點(diǎn),計(jì)算 totalRange 前,先將 String 轉(zhuǎn)成了 NSString,這是因?yàn)榇颂?NSRange 中的 length 需要的是 UTF-16 長(zhǎng)度,也就是與 NSString 的 length 定義一致,而 Swift 中的 String 沒(méi)有 length 只有 count,指的是字符數(shù),當(dāng)文本中出現(xiàn) emoji 表情時(shí),二者就不一致了。

當(dāng)然,也有一些其他辦法來(lái)處理,如:

let lengthA = inputTextView.textStorage.length
let lengthB = inputTextView.attributedText.string.utf16.count

2.點(diǎn)擊事件

實(shí)現(xiàn)高亮部分的點(diǎn)擊事件,目前有3種實(shí)現(xiàn)方案:

  • 直接給UITextView添加點(diǎn)擊事件
  • 通過(guò)設(shè)置LinkAttribute,利用超文本鏈接的點(diǎn)擊實(shí)現(xiàn)
  • 重寫UITextViewtouches...方法

其中,第二種只限于在非編輯狀態(tài)(即 textView.isEditable = false)下的點(diǎn)擊,故排除,①、③均可,本文采用第一種,主要實(shí)現(xiàn)如下:

inputTextView.addTapGesture(self, handler: #selector(tapAttributedText(tap:)))
@objc private func tapAttributedText(tap: UITapGestureRecognizer) {
    guard tap.isKind(of: UITapGestureRecognizer.self), let textView = tap.view as? UITextView else {
        return
    }
    let layoutManager = textView.layoutManager
    var tapLocation = tap.location(in: textView)
    tapLocation.x -= textView.textContainerInset.left
    tapLocation.y -= textView.textContainerInset.top
    let characterIndex = layoutManager.characterIndex(for: tapLocation,
                                                      in: textView.textContainer,
                                                      fractionOfDistanceBetweenInsertionPoints: nil)
    for result in getCheckResult(format: Constants.TopicRegularExpression, text: inputTextView.attributedText.string) {
        if result.range.location < characterIndex, characterIndex < result.range.location + result.range.length {
            // 此處響應(yīng)點(diǎn)擊事件
            MBProgressHUD.showOnlyText(to: self.view, title: "美好時(shí)光")
            return
        }
    }
    inputTextView.becomeFirstResponder()
}

@提及用戶

  • 編輯過(guò)程中 @提及用戶 實(shí)時(shí)高亮,且只允許選取的用戶名高亮,手動(dòng)輸入不高亮;

  • 點(diǎn)擊刪除鍵的時(shí)候,一次性刪除整個(gè)高亮部分

1.高亮

  • 記錄位置

本來(lái)準(zhǔn)備用正則匹配的,但因?yàn)橹辉试S選取的用戶名高亮,純手動(dòng)輸入的不高亮,所以使用正則匹配就不合理了,這里采用實(shí)時(shí)記錄、更新已選取用戶名位置的方式實(shí)現(xiàn)。

/// 用來(lái)保存已選取用戶信息的結(jié)構(gòu)體
struct UserInfo {
    /// 用戶名
    var userName: String
    /// 位置信息
    var range: NSRange
    /// 用于臨時(shí)替換的等長(zhǎng)字符串
    var placeholder: String
}
  • 臨時(shí)替換

因?yàn)?code>#話題#和@提及用戶可以同時(shí)存在,所以需要考慮可能互相影響的問(wèn)題,比如@提及用戶中間可能出現(xiàn)#,導(dǎo)致前后話題的正則匹配發(fā)生錯(cuò)亂。

解決方案是:先使用一個(gè)@開(kāi)頭且與@提及用戶等長(zhǎng)的字符串替換@提及用戶,再執(zhí)行#話題#的正則匹配,最后再換回來(lái)。

2.整體刪除

刪除操作分為兩步:第一次點(diǎn)刪除僅選中整個(gè)用戶名(提醒用戶是整體刪除);第二次點(diǎn)刪除才真的刪除文本。

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    if text == "" {
        for (num, user) in usersArray.enumerated() { // usersArray 用于存放已選取的用戶信息
            // ②刪除選中的用戶名
            if textView.selectedRange.location <= user.range.location && NSMaxRange(user.range) <= NSMaxRange(textView.selectedRange) {
                textView.replace(textView.selectedTextRange ?? UITextRange(), withText: "")
                return false
            }
            // ①選中用戶名
            if textView.selectedRange.length == 0 && (textView.selectedRange.location == user.range.location + user.range.length) {
                textView.selectedRange = user.range
                return false
            }
        }
    }
}

到此這篇關(guān)于iOS UITextView 實(shí)現(xiàn)類似微博的話題、提及功能的文章就介紹到這了,更多相關(guān)iOS UITextView微博話題內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • NSURLSession跨域重定向透?jìng)鱄TTP Header問(wèn)題解決

    NSURLSession跨域重定向透?jìng)鱄TTP Header問(wèn)題解決

    這篇文章主要為大家介紹了NSURLSession跨域重定向透?jìng)鱄TTP Header問(wèn)題解決方案,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • iOS開(kāi)發(fā)網(wǎng)絡(luò)編程之?dāng)帱c(diǎn)續(xù)傳

    iOS開(kāi)發(fā)網(wǎng)絡(luò)編程之?dāng)帱c(diǎn)續(xù)傳

    在下載較大的文件的時(shí)候,一次不能下載完畢,這就需要用到斷點(diǎn)續(xù)傳,那么在IOS開(kāi)發(fā)中該如何實(shí)現(xiàn)呢,下面跟著小編一起通過(guò)本文來(lái)學(xué)習(xí)下。
    2016-08-08
  • IOS安裝CocoaPods詳細(xì)教程

    IOS安裝CocoaPods詳細(xì)教程

    這篇文章主要為大家詳細(xì)介紹了IOS安裝CocoaPods教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • iOS實(shí)現(xiàn)聊天輸入框功能

    iOS實(shí)現(xiàn)聊天輸入框功能

    大家都經(jīng)常使用微信聊天功能,在沒(méi)事的時(shí)候就會(huì)想微信聊天輸入框的實(shí)現(xiàn)過(guò)程,很無(wú)聊吧。今天小編抽空給大家分享iOS實(shí)現(xiàn)聊天輸入框功能,感興趣的朋友跟隨腳本之家小編一起看看吧
    2018-02-02
  • IOS實(shí)現(xiàn)圓形圖片效果的兩種方法

    IOS實(shí)現(xiàn)圓形圖片效果的兩種方法

    這篇文章介紹在IOS中如何實(shí)現(xiàn)圓形圖片,實(shí)現(xiàn)后的效果很贊,有需要的可以參考借鑒。
    2016-08-08
  • iOS對(duì)象指針和基礎(chǔ)數(shù)據(jù)類型的強(qiáng)轉(zhuǎn)詳解

    iOS對(duì)象指針和基礎(chǔ)數(shù)據(jù)類型的強(qiáng)轉(zhuǎn)詳解

    最近在做一些小功能,忽然發(fā)現(xiàn)有的基礎(chǔ)數(shù)據(jù)轉(zhuǎn)換居然都忘記了。于是想著要趕緊整理下記下來(lái)!本文就是記錄的一些內(nèi)容,主要介紹了iOS中對(duì)象指針和基礎(chǔ)數(shù)據(jù)類型的強(qiáng)轉(zhuǎn),有需要的朋友們可以參考借鑒,下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2016-11-11
  • iOS中3DTouch預(yù)覽導(dǎo)致TableView滑動(dòng)卡頓問(wèn)題解決的方法

    iOS中3DTouch預(yù)覽導(dǎo)致TableView滑動(dòng)卡頓問(wèn)題解決的方法

    這篇文章主要給大家介紹了關(guān)于iOS中3DTouch預(yù)覽導(dǎo)致TableView滑動(dòng)卡頓問(wèn)題解決的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)同樣遇到的朋友們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起看看吧。
    2018-03-03
  • IOS提醒用戶重新授權(quán)打開(kāi)定位功能

    IOS提醒用戶重新授權(quán)打開(kāi)定位功能

    這篇文章主要介紹了IOS提醒用戶重新授權(quán)打開(kāi)定位功能的相關(guān)資料,需要的朋友可以參考下
    2015-12-12
  • UIScrollView實(shí)現(xiàn)六棱柱圖片瀏覽效果

    UIScrollView實(shí)現(xiàn)六棱柱圖片瀏覽效果

    這篇文章主要為大家介紹了UIScrollView實(shí)現(xiàn)六棱柱圖片瀏覽效果示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • iOS中利用CAEmitterLayer實(shí)現(xiàn)粒子動(dòng)畫詳解

    iOS中利用CAEmitterLayer實(shí)現(xiàn)粒子動(dòng)畫詳解

    粒子效果應(yīng)該對(duì)現(xiàn)在很多人來(lái)說(shuō)并不陌生,我們之前也分享了一些相關(guān)文章,下面這篇文章主要給大家介紹了關(guān)于iOS中利用CAEmitterLayer實(shí)現(xiàn)粒子動(dòng)畫的相關(guān)資料,文中介紹的非常詳細(xì),需要的朋友們下面來(lái)一起看看吧。
    2017-06-06

最新評(píng)論

阜平县| 鹤岗市| 漳平市| 西和县| 靖州| 马公市| 湟中县| 奎屯市| 上饶县| 全南县| 浙江省| 公主岭市| 克什克腾旗| 宜春市| 浙江省| 淳安县| 共和县| 英德市| 新兴县| 江口县| 福泉市| 盐津县| 北碚区| 泸定县| 辽源市| 武安市| 陵水| 兴城市| 增城市| 荥阳市| 阿拉善盟| 辽宁省| 黄平县| 浦东新区| 鹤岗市| 泌阳县| 安国市| 高淳县| 尤溪县| 石门县| 房产|