0.はじめに
Swift で UITextView に表示される URL リンクを短縮表示させたかったので、やってみました。
ついでに、キーワード検索時の強調表示もできる様にしてます。
以下の記事を参考にさせて頂きました。
感謝 ♪♪♪
🙇♂️🙇♂️🙇♂️
1.コード
今回は、UITextView の Extension として、setAttributedText
という関数を追加しました。
パラメータの説明は、以下。
-
text: String
: [元となるテキスト文字列] -
shortUrlMaxNum: Int = Int()
: [短縮されるURLの最大文字数] -
keyword: String? = nil
: [検索キーワード] -
keywordBackgroundColor: UIColor = .yellow
: [検索キーワードの強調される背景色]
UITextView+Extension.swift
//
// UITextView+Extension.swift
//
import UIKit
extension UITextView {
func setAttributedText(text: String, shortUrlMaxNum: Int = Int(), keyword: String? = nil, keywordBackgroundColor: UIColor = .yellow) -> Int {
var tempText: String = text
var links: [(url: URL, range: NSRange)] = []
if shortUrlMaxNum > 0 {
if let _detector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) {
var truncateCount: Int = 0
for link in _detector.matches(in: tempText, range: NSMakeRange(0, tempText.utf16.count)) {
let startIndex = tempText.utf16.index(tempText.startIndex, offsetBy: (link.range.location - truncateCount))
let endIndex = tempText.utf16.index(startIndex, offsetBy: link.range.length)
let _tempText = tempText[startIndex..<endIndex]
if let _url = link.url, let _ = _url.host, _tempText == _url.absoluteString {
var range: NSRange = link.range
if _url.absoluteString.count > shortUrlMaxNum {
let replacementString: String = _url.absoluteString.prefix(shortUrlMaxNum) + "..."
range = NSMakeRange(link.range.location - truncateCount, replacementString.count)
tempText.replaceSubrange(
Range<String.Index>(NSMakeRange(range.location, link.range.length), in: tempText)!,
with: replacementString)
truncateCount += (link.range.length - replacementString.count)
} else {
range = NSMakeRange(link.range.location - truncateCount, _url.absoluteString.count)
}
links.append((url: _url, range: range))
}
}
}
}
let attrText: NSMutableAttributedString = NSMutableAttributedString(string: tempText, attributes: [
.font : self.font as Any,
.foregroundColor : self.textColor as Any,
])
for link in links {
attrText.addAttribute(.link, value: link.url.absoluteString, range: link.range)
}
if let _keyword = keyword {
if let _regex = try? NSRegularExpression(pattern: _keyword) {
for match in _regex.matches(in: tempText, range: NSMakeRange(0, tempText.count)) as [NSTextCheckingResult] {
attrText.addAttribute(.backgroundColor, value: keywordBackgroundColor, range: match.range)
}
}
}
self.attributedText = attrText
return self.attributedText.string.count
}
}
で、こんな感じに表示されます。
99.ハマりポイント
短縮URL後のテキスト文字列の編集が、結構面倒臭かったですね…。バグってないかちょっと心配…。
あと、
tempText.utf16
を使っている箇所がありますが、これは絵文字対策で入れたものです。これも、結構面倒臭かった…。
😭😭😭
XX.まとめ
もしかしたら、バグあるかもしれないので、実装する場合は、自己責任でお願いします!
🙇♂️🙇♂️🙇♂️
あと、もっと簡単な方法があれば、教えて頂けるとと嬉しいです!
以上、ご参考になれば ♪♪♪
👋👋👋