当键盘正在显示时,检测UITextView中带属性的文本上的轻击操作。

8

这是对我先前回答的问题的补充问题, 关于在iOS中检测UITextView上属性文本的轻击。

我在Xcode 7.1.1和iOS 9.1上重新测试了以下代码,并且它与我链接的答案描述的设置一起正常工作。

import UIKit
class ViewController: UIViewController, UIGestureRecognizerDelegate {

    @IBOutlet weak var textView: UITextView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Create an attributed string
        let myString = NSMutableAttributedString(string: "Swift attributed text")

        // Set an attribute on part of the string
        let myRange = NSRange(location: 0, length: 5) // range of "Swift"
        let myCustomAttribute = [ "MyCustomAttributeName": "some value"]
        myString.addAttributes(myCustomAttribute, range: myRange)

        textView.attributedText = myString

        // Add tap gesture recognizer to Text View
        let tap = UITapGestureRecognizer(target: self, action: Selector("myMethodToHandleTap:"))
        tap.delegate = self
        textView.addGestureRecognizer(tap)
    }

    func myMethodToHandleTap(sender: UITapGestureRecognizer) {

        let myTextView = sender.view as! UITextView
        let layoutManager = myTextView.layoutManager

        // location of tap in myTextView coordinates and taking the inset into account
        var location = sender.locationInView(myTextView)
        location.x -= myTextView.textContainerInset.left;
        location.y -= myTextView.textContainerInset.top;

        // character index at tap location
        let characterIndex = layoutManager.characterIndexForPoint(location, inTextContainer: myTextView.textContainer, fractionOfDistanceBetweenInsertionPoints: nil)

        // if index is valid then do something.
        if characterIndex < myTextView.textStorage.length {

            // print the character index
            print("character index: \(characterIndex)")

            // print the character at the index
            let myRange = NSRange(location: characterIndex, length: 1)
            let substring = (myTextView.attributedText.string as NSString).substringWithRange(myRange)
            print("character at index: \(substring)")

            // check if the tap location has a certain attribute
            let attributeName = "MyCustomAttributeName"
            let attributeValue = myTextView.attributedText.attribute(attributeName, atIndex: characterIndex, effectiveRange: nil) as? String
            if let value = attributeValue {
                print("You tapped on \(attributeName) and the value is: \(value)")
            }

        }
    }
}

然而,如果更改了UITextView的设置,使其既可编辑又可选择

enter image description here

如果这样做,键盘将显示。键盘显示后,点击事件处理程序将不再被调用。如何在键盘显示时检测属性文本上的点击?
更新
尽管此处的代码是用Swift编写的,但最初提出此问题(在我上面链接的答案的评论中)的人正在使用Objective-C。因此,我很乐意接受Swift或Objective-C的答案。

我想使用Objective-C获取被点击的字符串,你知道如何编写这段代码吗? - Eleanor
@Liu - 你已经看到这个问题了吗?在iOS的UITextView中检测带属性的文本的轻敲? 它有几个Objective-C的答案。 - Suragch
是的,但我只想点击特定文本一次,换句话说,当我点击一个单词时,我想从该单词中删除属性,以便我无法再次点击它,我不知道如何做到这一点,你有什么想法吗? - Eleanor
我不懂Objective-C,但是处理过程应该是获取点击位置单词的范围,然后从该范围中删除属性。如果你找不到Stack Overflow上的问题和答案来告诉你如何做,那么你可以自己编写代码。(并在此处添加评论中的链接)。 - Suragch
这是一个触摸事件冲突。有两种可能的解决方案:1:将轻拍手势添加到TextField的父视图中,并可以将delaysTouchesBegan设置为YES,以优先处理您的手势。2:子类化TextField并在自定义的touchesBegan方法中处理轻拍事件。 - SolaWing
1个回答

0
在你的UITextView控制器中,你可以实现UITextViewDelegate,然后重写方法。
-(BOOL)textViewShouldBeginEditing:(UITextView *)textView{
}

在这个方法中,您可以访问textView的selectedRange,该range应该也是您属性文本的“tap range”。然后根据您的需要返回true/false。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接