检测 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 现在将点击传递到它们拥有的单元格以执行翻转动画!
抱歉耽搁了,但为了后代,next
是UIResponder
的成员: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 更改