检测 UITextView 上的点击仅检测取消 [重复]

Posted

技术标签:

【中文标题】检测 UITextView 上的点击仅检测取消 [重复]【英文标题】:Detecting tap on a UITextView only detects cancellations [duplicate] 【发布时间】:2015-07-07 14:42:31 【问题描述】:

我一直在努力用 Swift 检测 UITextView 上的点击。

我的 UITextViews 在一个表格中,我必须能够检测到链接并按下它们,这些链接的长度是未知的。

此外,如果我点击单元格,我不点击链接,我想在我的导航控制器堆栈上推送一个新的 UIViewController。

我尝试创建自己的 textview 来覆盖 touchesCancelled,但没有成功。它检测到不被视为在真实设备上点击的取消。

模拟器中没有出现这个bug,但是在真机上好像打不开,只能长按了。

class LinkTextView: UITextView 
    override func touchesCancelled(touches: Set<NSObject>!, withEvent event: UIEvent!) 
         self.textViewWasTapped(self) 
    

我尝试直接添加手势识别器。我在那里也没有任何成功。它根本不调用手势识别器。

我将 UIGestureReconizer 委托添加到我的 UIViewController 和我的那些行中

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
     var singleTap : UIGestureRecognizer = UIGestureRecognizer(target: self, action: "tapTextView:")
        singleTap.delegate = self
             cell.mTextOutlet.attributedText = myMutableString
             cell.mTextOutlet.addGestureRecognizer(singleTap) 

在我的 LinkTextView 类中:

class LinkTextView: UITextView 
    func tapTextView(stapGesture: UIGestureRecognizer)
        println("TAPPING1")
    

我查看了论坛并找到了这个帖子:post。它建议使用CHHLinkTextView。我尝试使用它,但我想要的是自动检测链接,正常的 uitextview 实际上是这样做的。

我确实尝试使用界面生成器中的复选框来解析带有 CHHLinkTextView 的链接,但它不起作用。我在文档中没有看到任何暗示可以这样做的内容。

我应该如何进行?

【问题讨论】:

【参考方案1】:

第一次尝试子类化 UITextView 已经非常接近了,但不是只覆盖 touchesCancelled,而是要覆盖所有 touches* 方法,即

touchesBegan touchesMoved touchesEnded touchesCancelled

在被覆盖的方法中,通过获取 textView 的 nextResponder() 将触摸发送到响应者链,检查它是否不是 nil,然后在下一个响应者上调用该方法。

之所以可行,是因为UITextView 将在 URL 上拦截触摸,并且永远不会调用 UIResponder 方法——通过在 tableViewCell 或任何地方实现 textView:shouldInteractWithURL:inRange 自己尝试一下,并且你会看到它在任何触摸事件传递之前被调用。

这应该是您尝试做的最低要求(重复但简短):

class PassThroughTextView: UITextView 

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 
        if let next = next 
            next.touchesBegan(touches, with: event)
         else 
            super.touchesBegan(touches, with: event)
        
    

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) 
        if let next = next 
            next.touchesEnded(touches, with: event)
         else 
            super.touchesEnded(touches, with: event)
        
    

    override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) 
        if let next = next 
            next.touchesCancelled(touches, with: event)
         else 
            super.touchesCancelled(touches, with: event)
        
    

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) 
        if let next = next 
            next.touchesMoved(touches, with: event)
         else 
            super.touchesMoved(touches, with: event)
        
    


// In case you want to do anything with the URL or textView in your tableViewCell...
class TableViewCell: UITableViewCell, UITextViewDelegate 
    @IBOutlet var textView: PassThroughTextView!

    func textView(textView: UITextView, shouldInteractWithURL URL: NSURL, inRange characterRange: NSRange) -> Bool 
        println("textView shouldInteractWithURL")
        return true
    


【讨论】:

next 来自哪里? 我猜它是作为某种超类继承的(可能是 NSObject 或 UIView)。感谢您的简单回答。这对我有用 :] 我的 UICollectionViewCell 带有嵌套的 UITextView 现在将点击传递到它们拥有的单元格以执行翻转动画! 抱歉耽搁了,但为了后代,nextUIResponder 的成员:developer.apple.com/documentation/uikit/uiresponder【参考方案2】:

我按照 Ralfonso 所说的做了,但没有成功,但它帮助我意识到我遇到了手势识别器冲突。原来我不必重写 UITextView 的所有 4 个方法,我只是重写了 touchesBegan。 我在 viewDidLoad 中所做的是添加一个手势识别器来关闭键盘:

      var tapOutTextField: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "dismissKeyboard")
      self.view.addGestureRecognizer(tapOutTextField)

没有意义并使我误入歧途的是 touchesBegan 实际上是在延迟后调用的(touchCancelled 也是如此),我无法获得与 UIButton 相同的行为。这一切都是因为这个手势识别器冲突。

【讨论】:

很高兴你能把它整理出来!手势识别器与引擎盖下的所有其他东西看起来很奇怪——在调查你的问题之前,我不知道抢先链接交互,所以 TIL。但是要记住一件事,如果您没有在 touchesBegan: 中调用 super,文档说您还必须覆盖其他触摸处理方法:developer.apple.com/library/ios/documentation/UIKit/Reference/…:避免以后出现奇怪行为可能是个好主意开。

以上是关于检测 UITextView 上的点击仅检测取消 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

仅检测伪元素上的点击事件

检测换行符以在 iOS 上的 UITextView 上自动输入换行文本

在不使用委托方法的情况下检测 UITextView 和/或 UITextField 上的 SELECTION 更改

如何检测NSTextAttachment上的触摸

UITextView应检测链接,否则应传播触摸以查看下面的链接

在缓冲模式下打开行编辑器时检测网格上的单击