'Tappable portions within a string for SwiftUI
I'm trying to add tappable segments to a Text and I have most of it but I cannot make an array of Texts with .onTapGestures. How can I add the tap gestures to the Texts. The goal is to have a string such as "here is a phone: xxx-xxx-xxxx and here is a link: xxx.com. Go for it." and have xxx-xx-xxx and xxx.com tappable.
@available(iOS 14, *)
struct ConversationText: View {
var text: String
var connectMessageType: ConnectMessageType
var stringArray = [String]()
var phones = [String]()
var weblinks = [String]()
var textArray = [Text]()
init(text: String, connectMessageType: ConnectMessageType) {
self.text = text
self.connectMessageType = connectMessageType
stringArray = text.components(separatedBy: " ")
phones = phones(from: text) ?? [String]()
weblinks = weblinks(from: text) ?? [String]()
textArray = makeTexts(from: stringArray)
}
var myColor: Color {
connectMessageType == .me ? .secondaryYellow : .primaryBlue
}
var body: some View {
textArray.reduce(Text(""), { $0 + $1 })
}
func phones(from text: String) -> [String]? {
Tappables().getPhoneNumbers(from: self.text)
}
func weblinks(from text: String) -> [String]? {
Tappables().getWebLinks(from: self.text)
}
func makeTexts(from stringArray: [String]) -> [Text] {
var textArray = [Text]()
for string in stringArray {
if phones.contains(string) {
let text = Text(string+" ")
.foregroundColor(myColor)
// .onTapGesture {
// startCall(number: string, user: nil)
// }
textArray.append(text)
} else if weblinks.contains(string) {
let text = Text(string+" ")
.foregroundColor(myColor)
// .onTapGesture {
// if let url = URL(string: string),
// UIApplication.shared.canOpenURL(url){
// UIApplication.shared.open(url)
// }
textArray.append(text)
} else {
textArray.append(Text(string+" "))
}
}
return textArray
}
}```
Solution 1:[1]
Here is possible approach - use string formatted by Markdown.
Tested with Xcode 13.3 / iOS 15.4
A main part:
Text("here is a phone: [xxx-xxx-xxxx](tel:xxx-xxx-xxxx) and here is a link: [xxx.com](asperi://apple.com). Go for it.")
.onOpenURL {
print(">> got: \($0)")
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Asperi |