带有 UIViewRepresentable 的 SwiftUI 超链接

问题描述 投票:0回答:1

我正在尝试在

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
        }
    }
}
swiftui hyperlink uiviewrepresentable
1个回答
0
投票

这个问题似乎与在 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 委托方法保持不变。

© www.soinside.com 2019 - 2024. All rights reserved.