90946


`https://google.com/ hello https://google.com/
https://google.com/`という文字列があった際に`SwiftUI.Text`でリンク付きで表示させたいです。

以下のようにAttributedStringとRegexで実装したのですが、最初の`https://google.com/`にしかリンクがつきません

原因は`AttributedString.range(of:)`が1つ目にしかマッチしないことだとはわかっているのですが、対処法がわかりません。

`Range<AttributedString.Index>`から`Range<String.Index>`の変換できればできればいいのですが、わかりませんでした。

[code]

    import SwiftUI
    import RegexBuilder
    
    struct ContentView: View {
      var attributedString: AttributedString {
        let inputText: String = "https://google.com/ hello https://google.com/ https://google.com/"
        var attributedText = AttributedString(inputText)
    
        let regex = Regex {
          OneOrMore(.url())
        }
    
        for match in inputText.matches(of: regex) {
          let range = attributedText.range(of: match.0)!
          attributedText[range].link = URL(string: String(match.0))!
        }
    
        return attributedText
      }
    
      var body: some View {
        Text(attributedString)
      }
    }
    
[/code]


CC BY-SA 4.0
2022-08-24T13:44:09.183
90737
2022-09-05T15:46:42.590
40856
question
swift swiftui
AttributedStringとRegexを使って文字列内のURLにリンクをつけたい


<https://zenn.dev/en3_hcl/articles/34ae63714a4daf>
の記事で紹介されている以下を使えば全てのrangeを取れるようです。

[code]

    extension AttributedString {
        func ranges<T: StringProtocol>(of stringToFind: T) -> [Range<AttributedString.Index>] {
            var ranges: [Range<AttributedString.Index>] = []
            var substring = self[self.startIndex ..< self.endIndex]
            while let range = substring.range(of: stringToFind) {
            ranges.append(range)
                substring = self[range.upperBound...]
        }
            return ranges
        }
    }
    
[/code]


CC BY-SA 4.0
2022-09-05T15:46:42.590
90946
2022-09-05T15:46:42.590
40856
90737
answer