【问题标题】:Detecting taps on attributed text in a UITextView while the keyboard is showing在显示键盘时检测 UITextView 中属性文本的点击
【发布时间】:2016-02-13 13:10:15
【问题描述】:

这是对a previous answer of mine 问题Detecting taps on attributed text in a UITextView in iOS 的补充问题。

我使用 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 设置更改为可编辑和可选择

然后这将导致键盘显示。显示键盘后,不再调用点击事件处理程序。如何在键盘显示时检测对属性文本的点击?

更新

虽然这里的代码是用 Swift 编写的,但最初提出这个问题的人(在对我上面链接的答案的评论中)正在使用 Objective-C。所以我很乐意接受 Swift 或 Objective-C 的答案。

【问题讨论】:

  • 我想得到用objective c敲击的字符串,你知道那段代码怎么写吗?
  • @Liu - 你已经看到问题Detecting taps on attributed text in a UITextView in iOS了吗?它有几个在 Objective-C 中的答案。
  • 是的,但是我只想点击某个文本一次,换句话说,当我点击一个单词时,我想从该单词中删除属性,这样我就不能点击它两次,我不知道怎么做,你知道吗?
  • 我不知道 Objective-C,但过程是在点击位置获取单词的范围,然后从该范围中删除属性。如果您找不到告诉您如何操作的 Stack Overflow 问题和答案,那么您可以自己编写。 (并在此处添加评论中的链接。)
  • 这是一个触摸事件冲突。这里有两种可能的解决方案: 1:在TextField的superview中添加点击手势,并且可以将delaysTouchesBegan设置为YES,以优先考虑您的手势。 2:子类 TextField 并在您的自定义 touchesBegan 方法中处理点击。

标签: ios objective-c swift uitextview touch-event


【解决方案1】:

在你的 UITextView 的控制器中,你可以实现 UITextViewDelegate ,然后重写方法

-(BOOL)textViewShouldBeginEditing:(UITextView *)textView{
}

在此方法中,您可以访问 textView 的 selectedRange,它也应该是属性文本的“点击范围”。然后根据您的需要返回 true / false。

【讨论】:

    猜你喜欢
    • 2013-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-24
    相关资源
    最近更新 更多