我正在尝试在
HyperLink
中使用 UITextView
创建 UIViewRepresentable
但我在 UITextView 中看不到任何文本。
使用:
ArtieHyperLink(url: "https://www.google.com.tr", text: "This is HyperLink test.", hyperText: "test")
UIView代表:
struct ArtieHyperLink: UIViewRepresentable {
var url: String = ""
var text: String = ""
var hyperText: String = ""
func makeUIView(context: Context) -> UITextView {
let textView = UITextView()
textView.delegate = context.coordinator
textView.isEditable = false
textView.isSelectable = true
textView.dataDetectorTypes = [.link]
textView.textColor = .black
textView.backgroundColor = .clear
textView.textAlignment = .center
textView.font = .systemFont(ofSize: 16)
let attributedString = NSMutableAttributedString(string: text)
let range = (attributedString.string as NSString).range(of: hyperText)
let url = URL(string: url)!
attributedString.addAttribute(.link, value: url, range: range)
textView.attributedText = attributedString
return textView
}
func updateUIView(_ textView: UITextView, context: Context) {
}
func makeCoordinator() -> Coordinator {
return Coordinator(self)
}
class Coordinator: NSObject, UITextViewDelegate {
var artieHyperLink: ArtieHyperLink
init(_ artieHyperLink: ArtieHyperLink) {
self.artieHyperLink = artieHyperLink
}
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
UIApplication.shared.canOpenURL(URL)
return false
}
}
}
这个问题似乎与在 UIViewRepresentable 结构的 makeUIView 方法中设置属性字符串有关。在 SwiftUI 中,makeUIView 方法仅在视图首次创建时被调用一次,后续对视图状态的更新由 updateUIView 方法处理。
要解决此问题,您可以尝试在 updateUIView 方法中设置属性字符串,并且仅在文本或超文本属性发生更改时更新文本视图的属性文本。这是您的 ArtieHyperLink 结构的更新版本:
struct ArtieHyperLink: UIViewRepresentable {
var url: String = ""
var text: String = ""
var hyperText: String = ""
func makeUIView(context: Context) -> UITextView {
let textView = UITextView()
textView.delegate = context.coordinator
textView.isEditable = false
textView.isSelectable = true
textView.dataDetectorTypes = [.link]
textView.textColor = .black
textView.backgroundColor = .clear
textView.textAlignment = .center
textView.font = .systemFont(ofSize: 16)
return textView
}
func updateUIView(_ textView: UITextView, context: Context) {
let attributedString = NSMutableAttributedString(string: text)
let range = (attributedString.string as NSString).range(of: hyperText)
let url = URL(string: url)!
attributedString.addAttribute(.link, value: url, range: range)
if textView.attributedText != attributedString {
textView.attributedText = attributedString
}
}
func makeCoordinator() -> Coordinator {
return Coordinator(self)
}
class Coordinator: NSObject, UITextViewDelegate {
var artieHyperLink: ArtieHyperLink
init(_ artieHyperLink: ArtieHyperLink) {
self.artieHyperLink = artieHyperLink
}
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
UIApplication.shared.canOpenURL(URL)
return false
}
}}
在这个更新的版本中,makeUIView 方法只创建和配置文本视图,属性字符串在 updateUIView 方法中设置。 updateUIView 方法使用更新的文本和超文本属性创建一个新的属性字符串,并且仅当它发生更改时才将其设置为文本视图的属性文本。 shouldInteractWith 委托方法保持不变。