Home 寫程式[SwiftUI] AttributedString and Hyperlink

[SwiftUI] AttributedString and Hyperlink

by 艾普利
Photo by Vladislav Klapin on Unsplash

Photo by Vladislav Klapin on Unsplash

記得還在寫 UIKit 的時候,其實很不喜歡寫 AttributedString 就覺得很麻煩,因為通常會有這樣的需求都是因為想要做超連結(Hyperlink),記得那時候要做到這樣是很麻煩的,除了要使用 AttributedString外,還要做點擊開網頁…通常……都會想盡辨法打消設計師們的念頭。

最近因為工作上的需要,所以就來去找找SwiftUI 要怎麼做超連結(Hyperlink)的方式,發現比起過去簡單很多,無論是在設定URL 或是 Handle Action 都很簡單,好用很多。

Text

若是想要在一串文字中間加上不同的字體或顏色,最常想到的就是 AttributedString ,不過,若不是想要做超連結的話,SwiftUI 的 Text 就可以做到了,像這樣:

 Text("Hello, world! ")
 +
 Text("Go google ")
   .foregroundColor(.orange)
 +
 Text("website")

印出來的結果會是這樣。

不過,如果想要加上 .onTapGesture 的話就沒有辨法了,用 + 串連的Text已經不是單純的 Text ,無法使用.onTapGesture 所以,想要做超連結的話,還是用AttributedString比較好。

AttributedString

AttributedString 是可以讓一串文字裡加入不同樣式的一種方式,這次特別寫出超連結的做法,它的做法是計算出特定字串的 Range ,再依據這個 Range 中的字是需要什麼樣式和顏色,只要能讓它知道需要不一樣的字是什麼,基本上就沒什麼問題。

AttributedString中的 AttributeScopes.FoundationAttributes 裡有提供 Link 參數,就是用來做為超連結使用的。

以下是實作方式

private func getLinkText(_ text: String, linkText: String, linkURL: String) -> AttributedString {
    var attributedString = AttributedString(text)
    attributedString.font = .systemFont(ofSize: 14, weight: .regular)
    attributedString.foregroundColor = Color.gray
        
    if let range = attributedString.range(of: linkText) {
        attributedString[range].font = .systemFont(ofSize: 14, weight: .medium)
        attributedString[range].foregroundColor = Color.orange
        attributedString[range].link = URL(string: linkURL)
    }
        
    return attributedString
}

解析一下程式碼

  • var attributedString = AttributedString(text) ,這裡的 text 需要是全部的句子
  • attributedString.range(of: linkText)linkText 就是想要做成超連結的文字段
  • attributedString[range].link,這裡寫入想要開啟的網站

fontforegroundColor 可以自行設定,應該有人有發現,像 ViewforegroundColor 已經Deprecated 了,現在都使用 foregroundStyle ,但這裡的 foregroundColorAttributeScopes裡的,不是 View 的喔。

Handle link

已經組好有中間有超連結的字串了,再來就直接用 Text 就可以了,最後的範例是要怎麼Handle link 行為

Text(getLinkText("Hello, world! Go google", linkText: "google", linkURL: "https://www.google.com.tw"))
                .environment(\.openURL, OpenURLAction { _ in
                    return .systemAction
                })

重要的就是使用 OpenURLAction ,與 environment(\.openURL) 一起使用,就可以Handle Link Text 點擊的行為,範例上寫的 .systemAction 的行為,就是指外開至Safari ,以下簡單說明 OpenURLAction 的回傳值。

  • handled : 就是自行處理,例如,想要直接用 .sheet 開啟網頁,這時候就需要 return handled。
  • discarded : 就是不做任何處理。
  • systemAction : 就是直接外開至Safari ,由Safari 幫你開網頁
  • systemAction(_:) : 是用 Safari 開,但是還可以帶別的 URL 或是需要加工URL (這個URL 是指Swift 裡的 URL 物件喔)

最後

只要記得上述這些東西,就可以比較簡單地寫出超連結的文字了,畢竟是手機,建議二組超連結的文字不要太近,不然很容易會點錯喔…

最後,祝大家 Coding 愉快!!

You may also like