首页 > 解决方案 > 是否有机会确定是否在 UITextView 中点击了空白空间?

问题描述

我在只读模式 + 手势识别器中使用 UITextView 使其可编辑以支持 URL,它工作得很好,但我遇到了问题:当用户在文本中只有 URL 并点击下面的空白空间时它使 UITextView 可编辑 - URL 被点击,用户被重定向到 URL。

预期行为:文本应变为可编辑。

该问题是由于以下代码引起的:

extension TextViewController : UIGestureRecognizerDelegate {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        if let textView = textView, textView.text.count > 0 {
            var location = touch.location(in: textView)
            location.x -= textView.textContainerInset.left
            location.y -= textView.textContainerInset.top
            let characterIndex = textView.layoutManager.characterIndex(for: location, in: textView.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
            if (textView.attributedText?.attribute(.link, at: characterIndex, effectiveRange: nil) as? URL) != nil {
                return false
            }
        }
        return true
    }
}

特别是由于“textView.layoutManager.characterIndex(for:location,in:textView.textContainer,fractionOfDistanceBetweenInsertionPoints:nil)”

它根据文档返回最后一位数字:

如果点下没有字符,则返回最近的字符

因此,代码的行为就像 URL 已被点击一样,我看不到任何选项来检查是否已点击了空白区域。这个想法是检查点击位置是否没有 URL,然后手势识别器应该收到点击(在此处返回 true)如果您有任何想法,请建议您如何做到这一点

谢谢!

标签: iosswifturluitextview

解决方案


好的,所以我让它按预期工作。解决方案是检查点击位置是否是文档的结尾:

if let position = textView.closestPosition(to: location) {
    if position == textView.endOfDocument {
        return true
    }
}

最终代码如下所示:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        if let textView = textView, textView.text.count > 0 {
            var location = touch.location(in: textView)
            location.x -= textView.textContainerInset.left
            location.y -= textView.textContainerInset.top
            if let position = textView.closestPosition(to: location) {
                if position == textView.endOfDocument {
                    return true
                }
            }
            
            let characterIndex = textView.layoutManager.characterIndex(for: location, in: textView.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
            if (textView.attributedText?.attribute(.link, at: characterIndex, effectiveRange: nil) as? URL) != nil {
                return false
            }
        }
        return true
    }

推荐阅读