同樣的,直接輸入“http://hangge.com”那麼微博中會顯示為可點擊的網頁鏈接。
1,讓textview支持特殊符號標簽
通常情況下,這些帶特殊標簽符號內容對於多行文本框(UITextView)來說都是視為普通文本,要想讓其支持點擊,我們可以借助textview的URL檢測功能來實現。
(1)首先遍歷文本內容,將各種特殊文本替換成我們自定義的一些 URL scheme。比如:用 mention://hangge 表示 @hangge,用 hash://航歌 表示 #航歌#(2)點擊“發送”按鈕則會將內容在上面一個textview中顯示出來,可以看到特殊符號的字段都顯示為可點擊狀態。
(3)測試下各個標簽的點擊響應事件。 3,實現步驟
2)擴展UITextView:UITextFieldExtension.swift
import UIKit
extension UITextView {
/**
轉換特殊符號標簽字段
*/
func resolveHashTags(){
let nsText:NSString = self.text
// 使用默認設置的字體樣式
let attrs = [NSFontAttributeName : self.font!]
let attrString = NSMutableAttributedString(string: nsText as String,
attributes:attrs)
//用來記錄遍歷字符串的索引位置
var bookmark = 0
//用於拆分的特殊符號
let charactersSet = NSCharacterSet(charactersInString: "@#")
//先將字符串按空格和分隔符拆分
let sentences:[NSString] = self.text.componentsSeparatedByCharactersInSet(
NSCharacterSet.whitespaceAndNewlineCharacterSet())
for sentence in sentences {
//如果是url鏈接則跳過
if !verifyUrl(sentence as String) {
//再按特殊符號拆分
let words:[NSString] = sentence.componentsSeparatedByCharactersInSet(
charactersSet)
var bookmark2 = bookmark
for i in 0..<words.count{
let word = words[i]
let keyword = chopOffNonAlphaNumericCharacters(word as String)
if keyword != "" && i>0{
//使用自定義的scheme來表示各種特殊鏈接,比如:mention:hangge
//使得這些字段會變藍色且可點擊
//匹配的范圍
let remainingRangeLength = min((nsText.length - bookmark2 + 1),
word.length+2)
let remainingRange = NSRange(location: bookmark2-1,
length: remainingRangeLength)
print(keyword, bookmark2, remainingRangeLength)
//匹配@某人
var matchRange = nsText.rangeOfString("@\(keyword)",
options: .LiteralSearch,
range:remainingRange)
attrString.addAttribute(NSLinkAttributeName,
value: "mention:\(keyword)",
range: matchRange)
//匹配#話題#
matchRange = nsText.rangeOfString("#\(keyword)#",
options: .LiteralSearch,
range:remainingRange)
attrString.addAttribute(NSLinkAttributeName,
value: "hash:\(keyword)",
range: matchRange)
}
//移動坐標索引記錄
bookmark2 += word.length + 1
}
}
//移動坐標索引記錄
bookmark += sentence.length + 1
}
print(nsText.length,bookmark)
//最終賦值
self.attributedText = attrString
}
/**
驗證URL格式是否正確
*/
private func verifyUrl(str:String) -> Bool {
// 創建一個正則表達式對象
do {
let dataDetector = try NSDataDetector(types:
NSTextCheckingTypes(NSTextCheckingType.Link.rawValue))
// 匹配字符串,返回結果集
let res = dataDetector.matchesInString(str,
options: NSMatchingOptions(rawValue: 0),
range: NSMakeRange(0, str.characters.count))
// 判斷結果(完全匹配)
if res.count == 1 && res[0].range.location == 0
&& res[0].range.length == str.characters.count {
return true
}
}
catch {
print(error)
}
return false
}
/**
過濾部多余的非數字和字符的部分
比如:@hangge.123 -> @hangge
*/
func chopOffNonAlphaNumericCharacters(text:String) -> String {
let nonAlphaNumericCharacters = NSCharacterSet
.alphanumericCharacterSet().invertedSet
let characterArray = text
.componentsSeparatedByCharactersInSet(nonAlphaNumericCharacters)
return characterArray[0]
}
}
(3)測試頁面代碼:
import UIKit
class ViewController: UIViewController, UITextViewDelegate {
//展示文本框
@IBOutlet weak var displayTextView: UITextView!
//編輯文本框
@IBOutlet weak var editTextView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
//設置展示文本框的代理
displayTextView.delegate = self
}
//發送消息
@IBAction func setMessage(sender: AnyObject) {
//設置展示文本框的內容
displayTextView.text = editTextView.text
//對內容中的特殊標簽字段做處理
displayTextView.resolveHashTags()
//清空輸入框內容
editTextView.text = ""
}
//展示文本框鏈接點擊響應
func textView(textView: UITextView, shouldInteractWithURL URL: NSURL,
inRange characterRange: NSRange) -> Bool {
//判斷URL scheme
switch URL.scheme {
case "hash" :
showAlert("hash", payload:
URL.resourceSpecifier.stringByRemovingPercentEncoding!)
case "mention" :
showAlert("mention", payload:
URL.resourceSpecifier.stringByRemovingPercentEncoding!)
default:
print("這個是普通的url鏈接")
}
return true
}
//顯示消息
func showAlert(tagType:String, payload:String){
let alertController = UIAlertController(title: "檢測到\(tagType)標簽",
message: payload, preferredStyle: .Alert)
let cancelAction = UIAlertAction(title: "確定", style: .Cancel, handler: nil)
alertController.addAction(cancelAction)
self.presentViewController(alertController, animated: true, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
原文出自:www.hangge.com