是否有机会确定是否在 UITextView 中点击了空 space?

is there any chance to identify if empty space has been tapped in UITextView?

我在只读模式下使用 UITextView + 手势识别器使其可编辑以支持 URLs,它工作得很好,但我遇到了问题: 当用户在文本中只有 URL 并点击其下方的空 space 以使 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(对于:位置,在:textView.textContainer,fractionOfDistanceBetweenInsertionPoints:零)”

根据文档,return是最后一位数字:

If no character is under the point, the nearest character is returned

因此代码的行为就像 URL 已被点击,我没有看到任何选项来检查是否已点击空 space。 这个想法是检查在点击的位置是否没有 URL 然后手势识别器应该接收点击(return 在这里) 如果您有任何想法,请提出建议

谢谢!

好的,我让它按预期工作了。解决方法是检查点击的位置是否为文档的末尾:

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
    }