UITextView 避免文本选择,但保留可点击的链接

Posted

技术标签:

【中文标题】UITextView 避免文本选择,但保留可点击的链接【英文标题】:UITextView avoid text selection, but keep tappable links 【发布时间】:2021-10-14 01:39:15 【问题描述】:

我有一个弹出窗口,显示用户的服务条款和隐私政策,如何禁用文本选择但保持链接可点击。 screenshot 如果我设置: 已解决:通过在 UIViewDelegate 中添加 textViewDidChangeSelection 方法并设置

textView.isSelectable = false
textView.isUserInteractionEnabled = true
textView.isSelectable = true

链接变得不可交互。 如何保持链接可点击且文本不可选择?

我的全班:

//  HyperLinkTextView.swift

import SwiftUI

struct Hyperlink 
    var word: String
    var url: NSURL


struct HyperLinkTextView: UIViewRepresentable 
    
    private var text: String
    private var links: [Hyperlink]
    let textView = UITextView()
    
    init(text: String, links: [Hyperlink]) 
        self.text = text
        self.links = links
    
    
    func makeUIView(context: Self.Context) -> UITextView 
        let attributedString = NSMutableAttributedString(string: text)
        links.forEach  hyperlink in
            let linkAttributes = [NSAttributedString.Key.link: hyperlink.url]
            
            var nsRange = NSMakeRange(0, 0)
            if let range = text.range(of: hyperlink.word) 
                nsRange = NSRange(range, in: text)
            
            
            attributedString.setAttributes(linkAttributes, range: nsRange)
            attributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSNumber(value: 1), range: nsRange)
        
        
        textView.isEditable = false
        textView.delegate = context.coordinator
        textView.attributedText = attributedString
        textView.linkTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor(Theme.colorClickables)]
        textView.isUserInteractionEnabled = true
        textView.isSelectable = true
    
        return textView
    
    
    func updateUIView(_ uiView: UITextView, context: Context) 
        uiView.font = UIFont(name: "ArialMT", size: 18)
    
    
    func makeCoordinator() -> Coordinator 
        Coordinator()
    
    
    
    public class Coordinator: NSObject, UITextViewDelegate, NSLayoutManagerDelegate 
        
        weak var textView: UITextView?
            
        public func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction, replacementText text: String) -> Bool 
            return true
        
        
        func textViewDidChangeSelection(_ textView: UITextView) 
            if textView.selectedTextRange != nil 
                textView.delegate = nil
                textView.selectedTextRange = nil
                textView.delegate = self
            
        
    

【问题讨论】:

【参考方案1】:

添加这个UITextViewDelegatetextViewDidChangeSelection并注释掉isEditableisSelectable

func textViewDidChangeSelection(_ textView: UITextView) 
    if textView.selectedTextRange != nil 
        textView.delegate = nil
        textView.selectedTextRange = nil
        textView.delegate = self
    

【讨论】:

不适合我,我把这个函数放在我的公共类 Coordinator 下,public func textView(),对吧? @ItaiAviv isUserInteractionEnabled 已启用?? @ItaiAviv 您在 SwiftUI 中的使用情况并使用源代码更新问题。 @ItaiAviv 这些isEditable isUserInteractionEnabled isSelectable 在代码库中仍然是错误的吗? 哇,对我有用,当设置isEditable = falseisUserInteractionEnabled = true isSelectable = true ,并使用你的代码块,谢谢)

以上是关于UITextView 避免文本选择,但保留可点击的链接的主要内容,如果未能解决你的问题,请参考以下文章

UITextView带有可点击链接但没有文字突出显示

UITextView 避免 collectionViewCell 被点击

UITextView 避免键盘滚动

在 UITextview 中获取被点击的单词

解除键盘后,带有所选文本的UITextView不响应触摸

禁用 UITextView 中的滚动,同时避免在 ios 的当前位置弹跳到顶部和文本不可见