Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Swift で UITextView の URL リンクを短縮表示させる。

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
    }
}


で、こんな感じに表示されます。

IMG_0152.png


99.ハマりポイント

  • 短縮URL後のテキスト文字列の編集が、結構面倒臭かったですね…。バグってないかちょっと心配…。

  • あと、tempText.utf16 を使っている箇所がありますが、これは絵文字対策で入れたものです。これも、結構面倒臭かった…。

😭😭😭

XX.まとめ

もしかしたら、バグあるかもしれないので、実装する場合は、自己責任でお願いします!

🙇‍♂️🙇‍♂️🙇‍♂️

あと、もっと簡単な方法があれば、教えて頂けるとと嬉しいです!

以上、ご参考になれば ♪♪♪

👋👋👋

kusokamayarou
鹿児島市の企業に勤めて、枕崎でテレワークしてる IT エンジニアです。 最近、自分で事業をしようとちょっとずつ動き始めました。
http://kusokamayarou.hatenablog.com/
genbasupport
建設業を支えるコミュニケーション&マネジメントのサービスを開発・運営するエンジニアチーム
http://www.genbasupport.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away