UITextInput.characterRange(at :)偏离几个像素

时间:2018-03-29 08:53:11

标签: ios uitextview uigesturerecognizer uitextinput uitextposition

在我的UITextView子类中添加了点击识别器之后,我正在尝试获取正在点击的字符:

var textRecognizer: UITapGestureRecognizer!
required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)

    textContainer.lineFragmentPadding = 0
    textContainerInset = .zero

    textRecognizer = UITapGestureRecognizer(target: self, action: #selector(textTapped))
    textRecognizer.numberOfTapsRequired = 1
    addGestureRecognizer(textRecognizer)
}

@objc func textTapped(recognizer: UITapGestureRecognizer) {
    let location = recognizer.location(in: self)
    if let cRange = characterRange(at: location) {
        let cPosition = offset(from: beginningOfDocument, to: cRange.start)
        let cChar = text[Range(NSRange(location: cPosition, length: 1), in: text)!]
        print(cChar)
    }
}

问题是,如果我的attributionText为"Hello world\nWelcome to Stack Overflow"并点击字母的左侧部分,例如字母f的左侧,则characterRange(at: location)会返回上一个字母{{ 1}}而不是返回r

1 个答案:

答案 0 :(得分:0)

从我的角度来看, characterRange(at :) 是错误的:




    

  • 如果你在索引 n的字符的左半部分给它一个点,它返回范围(n-1,n)
  • 

  • 如果你在索引 n <的字符的右半部分给它一个点/ code>,它返回范围(n,n + 1)
  • &#xA;
  • 如果你在索引的字符的左半部分给它一个点beginOfDocument ,它返回 nil
  • &#xA;
  • 如果你在索引 endOfDocument 的右半边给它一个点,它返回(endOfDocument,endOfDocument + 1)
  • &#xA;
&#xA;&#xA;

textInput示例极端行为的差异演示某处有一个bug。

&#xA;&#xA;

它的行为类似于“光点位置”功能,这使得确定哪个字符实际位于此点是不可靠的:是光标前的字符还是光标后的字符?

&#xA;&#xA;

nearestPosition(to:) 受到严重影响同样的问题。

&#xA;&#xA;

一个可行的替代方案是 layoutManager.characterIndex(for:in:fractionOfDistanceBetweenInsertionPoints:) 归功于vacawama

&#xA;&#xA;
  @objc func textTapped (识别器:UITapGestureRecognizer){&#xA; var location = recognizer.location(in:self)&#xA; location.x  -  = textContainerInset.left&#xA; location.y  -  = textContainerInset.top&#xA;让cPosition = layoutManager.characterIndex(for:location,in:textContainer,fractionOfDistanceBetweenInsertionPoints:nil)&#xA;让cChar = text [Range(NSRange(location:cPosition,length:1),in:text)!]&#xA;打印(CCHAR)&#XA;}&#XA;  
&#XA;