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
,這裡寫入想要開啟的網站
font
與 foregroundColor
可以自行設定,應該有人有發現,像 View
的 foregroundColor
已經Deprecated 了,現在都使用 foregroundStyle
,但這裡的 foregroundColor
是 AttributeScopes
裡的,不是 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 愉快!!