🌊

【SwiftUI】TextでURLリンクを扱う様々な方法

2024/06/20に公開

概要

SwiftUIのTextでURLリンクを生成する方法がいくつかあるので紹介します。

環境

iOS 17.0

Environment

struct ContentView: View {
    @Environment(\.openURL) var openURL
    var body: some View {
        VStack {
            Button {
                openURL(URL(string: "https://www.apple.com/jp")!)
            } label: {
                Text("URLを開く")
            }
        }
    }
}

Markdown

struct ContentView: View {
    var body: some View {
        VStack {
            Text("[Apple](https://www.apple.com/jp)")
        }
    }
}

AttributedString

struct ContentView: View {
    let text = "Apple リンクはこちらです。 https://www.example.com こちらをタップすることでリンクを開くことができます。"
    var body: some View {
        VStack {
            Text(makeAttributedString(text: text))
        }
    }
    func makeAttributedString(text: String) -> AttributedString {
        var attributedString = AttributedString(text)
        let detector = try! NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)

        let matches = detector.matches(in: text, options: [], range: NSRange(location: 0, length: text.utf16.count))

        for match in matches {
            guard let range = Range(match.range, in: text),
                  let attributedRange = Range(range, in: attributedString) else { continue }
            let url = text[range]
            if let url = URL(string: String(url)) {
                attributedString[attributedRange].link = url
            }
        }
        return attributedString
    }
}

まとめ

ユースケースに応じて以下の方法を使い分けると良いと思います。

  • ボタンを利用してリンクを開きたい場合 → Environmentを使用
  • 単純なリンクをテキスト内で表示したい場合 → Markdown形式を使用
  • リッチなテキスト内で動的なリンクを扱いたい場合 → AttributedStringを使用

Discussion