Error[8]: Undefined offset: 16, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

概述在社交类 APP 中 @、# 符号构成的标记文本已经形成了某种通用的意义:前者表示通知某位好友,而后者表示为某个话题或者分类。这些标记文本一般还都带有高亮显示和可点击的特点。接下来的我会创建一个 UITextView 的子类 AttrTextView 来实现上诉功能。 开始 import UIKitenum wordType{ case hashtag // #标示文本类型

在社交类 APP 中 @、# 符号构成的标记文本已经形成了某种通用的意义:前者表示通知某位好友,而后者表示为某个话题或者分类。这些标记文本一般还都带有高亮显示和可点击的特点。接下来的我会创建一个 UITextVIEw 的子类 AttrTextVIEw 来实现上诉功能。

开始
import UIKitenum wordType{    case hashtag   // #标示文本类型    case mention   // @标示文本类型}//自定义视图用于高亮 # 和 @ 之后的文本(效果类似于微博、twitter),并添加点击事件class AttrTextVIEw: UITextVIEw {    var textString: Nsstring?    var attrString: NSMutableAttributedString?    var callBack: ((String,wordType) -> VoID)?        ...}

上码的代码首先声明了一个 wordType 的枚举类型,该类用用于对标示文本进行类型标记。接着我们定义了自定义类型 AttrTextVIEw,并且声明了三个属性。textString 表示原文本,attrString 进行属性设置后的文本,callBack 为 # 和 @ 标记文本的点击事件回调。

文本设置

定义好属性后,我们就需要考虑使用接口的实现了。正常情况下文本应该有以下属性需要设置:常规文本的字体、颜色;# 和 @ 标记文本各自对应的字体和颜色;点击事件设置以及回调函数。代码如下:

public func setText(text: String,normalcolor: UIcolor,hashtagcolor: UIcolor,mentioncolor: UIcolor,normalFont: UIFont,hashTagFont: UIFont,mentionFont: UIFont,tapCallBack callBack: @escaPing (String,wordType) -> VoID) {    self.callBack = callBack    self.attrString = NSMutableAttributedString(string: text)    self.textString = Nsstring(string: text)        // Set initial Font attributes for our string    // 设置字体和文本颜色    attrString?.addAttribute(NSFontAttributename,value: normalFont,range: NSRange(location: 0,length: (textString?.length)!))    attrString?.addAttribute(NSForegroundcolorAttributename,value: normalcolor,length: (textString?.length)!))        // Call a custom set Hashtag and Mention Attributes Function    // 设置 #、@ 的高亮色等属性    setAttrWithname(attrname: "Hashtag",wordPrefix: "#",color: hashtagcolor,text: text,Font: hashTagFont)    setAttrWithname(attrname: "Mention",wordPrefix: "@",color: mentioncolor,Font: mentionFont)        // Add tap gesture that calls a function tapRecognized when tapped    // 添加手势    let tapper = UITapGestureRecognizer(target: self,action: #selector(self.tapRecognized(tapGesture:)))    addGestureRecognizer(tapper)}

上面代码中的 setAttrWithname 函数的目的是对 #、@ 标记文本的属性进行设置,代码如下:

private func setAttrWithname(attrname: String,wordPrefix: String,color: UIcolor,text: String,Font: UIFont) {    // Words can be separated by either a space or a line break    // 将文本按照空格和 \n 键拆分为单词数组    var words: [String] = []    let wordtext: [String] = text.components(separatedBy: " ")    for var word in wordtext {                if word.hasPrefix("\n") {            word = word.replacingOccurrences(of: "\n",with: "")        }        words.append(word)            }        // 便利数组,检查是否满足条件并进行属性设置    for word in words.filter({
func tapRecognized(tapGesture: UITapGestureRecognizer) {    var wordString: String?         // The String value of the word to pass into callback function    var char: NSAttributedString!   //The character the user clicks on. It is non optional because if the user clicks on nothing,char will be a space or " "    var word: NSAttributedString?   //The word the user clicks on    var isHashtag: AnyObject?    var isAtMention: AnyObject?            // Gets the range of the character at the place the user taps    // 检查用户点击字符的范围    let point = tapGesture.location(in: self)    let charposition = closestposition(to: point)                    guard let charRange = tokenizer.rangeEnclosingposition(charposition!,with: .character,inDirection: 1) else {        return    }            let location = offset(from: beginningOfdocument,to: charRange.start)    let length = offset(from: charRange.start,to: charRange.end)    let attrRange = NSMakeRange(location,length)    char = attributedText.attributedSubstring(from: attrRange)            // If the user has not clicked on anything,exit the function    if char.string == " "{        print("User clicked on nothing")        return    }            // Checks the character's attribute,if any    // 检查属性标示    isHashtag = char?.attribute("Hashtag",at: 0,longestEffectiveRange: nil,in: NSMakeRange(0,char!.length)) as AnyObject?    isAtMention = char?.attribute("Mention",char!.length)) as AnyObject?                            // Gets the range of the word at the place user taps    // 获得点击单词的范围    let wordRange = tokenizer.rangeEnclosingposition(charposition!,with: .word,inDirection: 1)                    /*    单词的范围在下面两种情况下为 nil:    1. 点击在 "#" or "@" 标示上    2. 没有点击在任何字符上。但是这种情况在上面的代码中已经排除了,所有只剩下 1    */    if wordRange != nil {        let wordLocation = offset(from: beginningOfdocument,to: wordRange!.start)        let wordLength = offset(from: wordRange!.start,to: wordRange!.end)        let wordAttrRange = NSMakeRange(wordLocation,wordLength)        word = attributedText.attributedSubstring(from: wordAttrRange)        wordString = word!.string    } else {        /*        右移12像素后再获取单词        */        var modifIEdPoint = point         modifIEdPoint.x += 12        let modifIEdposition = closestposition(to: modifIEdPoint)        let modifeDWordRange = tokenizer.rangeEnclosingposition(modifIEdposition!,inDirection: 1)        if modifeDWordRange != nil {            let wordLocation = offset(from: beginningOfdocument,to: modifeDWordRange!.start)            let wordLength = offset(from: modifeDWordRange!.start,to: modifeDWordRange!.end)            let wordAttrRange = NSMakeRange(wordLocation,wordLength)            word = attributedText.attributedSubstring(from: wordAttrRange)            wordString = word!.string        }    }            if let stringtopass = wordString {        // 点击回掉函数        if isHashtag != nil && callBack != nil {            callBack!(stringtopass,wordType.hashtag)        } else if isAtMention != nil && callBack != nil {            callBack!(stringtopass,wordType.mention)        }    }}
.hasPrefix(wordPrefix)}) { let range = textString!.range(of: word) attrString?.addAttribute(NSForegroundcolorAttributename,value: color,range: range) attrString?.addAttribute(attrname,value: 1,range: range) attrString?.addAttribute("Clickable",range: range) attrString?.addAttribute(NSFontAttributename,value: Font,range: range) } self.attributedText = attrString}
点击事件的处理

文本点击的处理稍微有点麻烦,需要考虑多种情况:

没有点击在任何文本上

点击在普通文本

点击在标示文本,并且需要识别标示文本的类型

.character

上面的代码处理中,首先使用 .character 检查点击位置的字符,并对无效区域的点击进行了处理。这里之所以使用 .word 而不是后面的 .word 的原因是:后者会将 @、# 这些标示符丢弃,导致一只类似点击到无效区域的情形。当上诉检查通过也就是点击区域有效的时候,我们使用

let attrVIEw = AttrTextVIEw.init(frame: CGRect.init(x: 0,y: 64,wIDth: vIEw.bounds.size.wIDth,height: vIEw.bounds.size.height - 64),textContainer: nil)    self.vIEw.addSubvIEw(attrVIEw)      attrVIEw.setText(text: "#PHP 是不是世界上最好的语言? @all ",normalcolor: .black,hashtagcolor: .red,mentioncolor: .blue,normalFont: UIFont.systemFont(ofSize: 10),hashTagFont:  UIFont.systemFont(ofSize: 14),mentionFont:  UIFont.systemFont(ofSize: 14)) { word,wordType in    print(word)}
,获取点击区域的单词。为了应对前面标示点击的情形,当区域无效的时候,我们右移12个像素后再获取单词。最后我们根据文本不同类型进行对应处理。

最后

最后我们看一下简单使用示例代码:

[+++] 总结

以上是内存溢出为你收集整理的可点击 @、# 标记文本实现全部内容,希望文章能够帮你解决可点击 @、# 标记文本实现所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
可点击 @、# 标记文本实现_app_内存溢出

可点击 @、# 标记文本实现

可点击 @、# 标记文本实现,第1张

概述在社交类 APP 中 @、# 符号构成的标记文本已经形成了某种通用的意义:前者表示通知某位好友,而后者表示为某个话题或者分类。这些标记文本一般还都带有高亮显示和可点击的特点。接下来的我会创建一个 UITextView 的子类 AttrTextView 来实现上诉功能。 开始 import UIKitenum wordType{ case hashtag // #标示文本类型

在社交类 APP 中 @、# 符号构成的标记文本已经形成了某种通用的意义:前者表示通知某位好友,而后者表示为某个话题或者分类。这些标记文本一般还都带有高亮显示和可点击的特点。接下来的我会创建一个 UITextVIEw 的子类 AttrTextVIEw 来实现上诉功能。

开始
import UIKitenum wordType{    case hashtag   // #标示文本类型    case mention   // @标示文本类型}//自定义视图用于高亮 # 和 @ 之后的文本(效果类似于微博、twitter),并添加点击事件class AttrTextVIEw: UITextVIEw {    var textString: Nsstring?    var attrString: NSMutableAttributedString?    var callBack: ((String,wordType) -> VoID)?        ...}

上码的代码首先声明了一个 wordType 的枚举类型,该类用用于对标示文本进行类型标记。接着我们定义了自定义类型 AttrTextVIEw,并且声明了三个属性。textString 表示原文本,attrString 进行属性设置后的文本,callBack 为 # 和 @ 标记文本的点击事件回调。

文本设置

定义好属性后,我们就需要考虑使用接口的实现了。正常情况下文本应该有以下属性需要设置:常规文本的字体、颜色;# 和 @ 标记文本各自对应的字体和颜色;点击事件设置以及回调函数。代码如下:

public func setText(text: String,normalcolor: UIcolor,hashtagcolor: UIcolor,mentioncolor: UIcolor,normalFont: UIFont,hashTagFont: UIFont,mentionFont: UIFont,tapCallBack callBack: @escaPing (String,wordType) -> VoID) {    self.callBack = callBack    self.attrString = NSMutableAttributedString(string: text)    self.textString = Nsstring(string: text)        // Set initial Font attributes for our string    // 设置字体和文本颜色    attrString?.addAttribute(NSFontAttributename,value: normalFont,range: NSRange(location: 0,length: (textString?.length)!))    attrString?.addAttribute(NSForegroundcolorAttributename,value: normalcolor,length: (textString?.length)!))        // Call a custom set Hashtag and Mention Attributes Function    // 设置 #、@ 的高亮色等属性    setAttrWithname(attrname: "Hashtag",wordPrefix: "#",color: hashtagcolor,text: text,Font: hashTagFont)    setAttrWithname(attrname: "Mention",wordPrefix: "@",color: mentioncolor,Font: mentionFont)        // Add tap gesture that calls a function tapRecognized when tapped    // 添加手势    let tapper = UITapGestureRecognizer(target: self,action: #selector(self.tapRecognized(tapGesture:)))    addGestureRecognizer(tapper)}

上面代码中的 setAttrWithname 函数的目的是对 #、@ 标记文本的属性进行设置,代码如下:

private func setAttrWithname(attrname: String,wordPrefix: String,color: UIcolor,text: String,Font: UIFont) {    // Words can be separated by either a space or a line break    // 将文本按照空格和 \n 键拆分为单词数组    var words: [String] = []    let wordtext: [String] = text.components(separatedBy: " ")    for var word in wordtext {                if word.hasPrefix("\n") {            word = word.replacingOccurrences(of: "\n",with: "")        }        words.append(word)            }        // 便利数组,检查是否满足条件并进行属性设置    for word in words.filter({
func tapRecognized(tapGesture: UITapGestureRecognizer) {    var wordString: String?         // The String value of the word to pass into callback function    var char: NSAttributedString!   //The character the user clicks on. It is non optional because if the user clicks on nothing,char will be a space or " "    var word: NSAttributedString?   //The word the user clicks on    var isHashtag: AnyObject?    var isAtMention: AnyObject?            // Gets the range of the character at the place the user taps    // 检查用户点击字符的范围    let point = tapGesture.location(in: self)    let charposition = closestposition(to: point)                    guard let charRange = tokenizer.rangeEnclosingposition(charposition!,with: .character,inDirection: 1) else {        return    }            let location = offset(from: beginningOfdocument,to: charRange.start)    let length = offset(from: charRange.start,to: charRange.end)    let attrRange = NSMakeRange(location,length)    char = attributedText.attributedSubstring(from: attrRange)            // If the user has not clicked on anything,exit the function    if char.string == " "{        print("User clicked on nothing")        return    }            // Checks the character's attribute,if any    // 检查属性标示    isHashtag = char?.attribute("Hashtag",at: 0,longestEffectiveRange: nil,in: NSMakeRange(0,char!.length)) as AnyObject?    isAtMention = char?.attribute("Mention",char!.length)) as AnyObject?                            // Gets the range of the word at the place user taps    // 获得点击单词的范围    let wordRange = tokenizer.rangeEnclosingposition(charposition!,with: .word,inDirection: 1)                    /*    单词的范围在下面两种情况下为 nil:    1. 点击在 "#" or "@" 标示上    2. 没有点击在任何字符上。但是这种情况在上面的代码中已经排除了,所有只剩下 1    */    if wordRange != nil {        let wordLocation = offset(from: beginningOfdocument,to: wordRange!.start)        let wordLength = offset(from: wordRange!.start,to: wordRange!.end)        let wordAttrRange = NSMakeRange(wordLocation,wordLength)        word = attributedText.attributedSubstring(from: wordAttrRange)        wordString = word!.string    } else {        /*        右移12像素后再获取单词        */        var modifIEdPoint = point         modifIEdPoint.x += 12        let modifIEdposition = closestposition(to: modifIEdPoint)        let modifeDWordRange = tokenizer.rangeEnclosingposition(modifIEdposition!,inDirection: 1)        if modifeDWordRange != nil {            let wordLocation = offset(from: beginningOfdocument,to: modifeDWordRange!.start)            let wordLength = offset(from: modifeDWordRange!.start,to: modifeDWordRange!.end)            let wordAttrRange = NSMakeRange(wordLocation,wordLength)            word = attributedText.attributedSubstring(from: wordAttrRange)            wordString = word!.string        }    }            if let stringtopass = wordString {        // 点击回掉函数        if isHashtag != nil && callBack != nil {            callBack!(stringtopass,wordType.hashtag)        } else if isAtMention != nil && callBack != nil {            callBack!(stringtopass,wordType.mention)        }    }}
.hasPrefix(wordPrefix)}) { let range = textString!.range(of: word) attrString?.addAttribute(NSForegroundcolorAttributename,value: color,range: range) attrString?.addAttribute(attrname,value: 1,range: range) attrString?.addAttribute("Clickable",range: range) attrString?.addAttribute(NSFontAttributename,value: Font,range: range) } self.attributedText = attrString}
点击事件的处理

文本点击的处理稍微有点麻烦,需要考虑多种情况:

没有点击在任何文本上

点击在普通文本

点击在标示文本,并且需要识别标示文本的类型

.character

上面的代码处理中,首先使用 .character 检查点击位置的字符,并对无效区域的点击进行了处理。这里之所以使用 .word 而不是后面的 .word 的原因是:后者会将 @、# 这些标示符丢弃,导致一只类似点击到无效区域的情形。当上诉检查通过也就是点击区域有效的时候,我们使用

let attrVIEw = AttrTextVIEw.init(frame: CGRect.init(x: 0,y: 64,wIDth: vIEw.bounds.size.wIDth,height: vIEw.bounds.size.height - 64),textContainer: nil)    self.vIEw.addSubvIEw(attrVIEw)      attrVIEw.setText(text: "#PHP 是不是世界上最好的语言? @all ",normalcolor: .black,hashtagcolor: .red,mentioncolor: .blue,normalFont: UIFont.systemFont(ofSize: 10),hashTagFont:  UIFont.systemFont(ofSize: 14),mentionFont:  UIFont.systemFont(ofSize: 14)) { word,wordType in    print(word)}
,获取点击区域的单词。为了应对前面标示点击的情形,当区域无效的时候,我们右移12个像素后再获取单词。最后我们根据文本不同类型进行对应处理。

最后

最后我们看一下简单使用示例代码:

总结

以上是内存溢出为你收集整理的可点击 @、# 标记文本实现全部内容,希望文章能够帮你解决可点击 @、# 标记文本实现所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1064382.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存