【问题标题】:Xcode 9 UITextView links no longer clickableXcode 9 UITextView 链接不再可点击
【发布时间】:2018-02-18 23:55:35
【问题描述】:

在 Xcode 9 和 iOS 11 之前,我在包含多个链接的 UITableViewCell 中有一个 UITextView。每个链接都按预期工作,但是自从升级到 iOS 11 和 Xcode 9 后,这些链接不再有效。

UITextView 似乎无法识别任何与func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool 从未触发的触摸交互。

有没有其他人在升级后发现同样的问题?

【问题讨论】:

  • 是的。这些设置需要到位才能在 ios11 之前使链接正常工作。我相信这是 ios11 中引入的更改,导致 UITextView 不再记录与 URL 的交互;文本是可选择的。
  • 问题似乎与UITextViewDelegate 有关。 UITableViewCell 设置为委托,这很好,但似乎不再起作用。我通过在单元格中实现func textViewDidBeginEditing(_ textView: UITextView) 对此进行了测试,我发现它并没有像interactwithURL 那样被调用。如果我将ViewController 设置为委托,则在ViewController 中调用该函数。
  • 代理应该是UITableViewCell。委托设置在override init(style: UITableViewCellStyle, reuseIdentifier: String?)
  • 我设法通过在ViewController 中实现interactwithURL 而不是通过将ViewController 设置为单元格的UITextViewDelegate 来实现UITableViewCell。很高兴听到任何其他更优雅的方法。感谢您的帮助马特。在单独的说明中,我注意到链接需要比以前在 ios10 中更牢固的按压才能注册。
  • 你应该回答你自己的问题;这是合法且受鼓励的,您的回答可能对其他人有用。在 48 小时内,您可以(并且应该)接受您自己的答案。 — 我想知道是否有什么东西在你设置之后让单元格不是成为委托。

标签: uitextview ios11


【解决方案1】:

事实证明毕竟没有问题。 iOS11 中 UITextView 响应触摸方式的变化意味着点击链接需要更多的按压,而不是之前在 iOS10 中工作的点击。我认为这可能与在 iOS11 中您现在可以按下链接并拖动它们也显示 URL 详细信息的事实有关。所以 UITextView 需要用力按压才能注册被点击的链接。

【讨论】:

  • 长按与点击不冲突,所以这仍然是一个错误。
  • 是的,这对我来说似乎也是如此。我认为这应该是一个错误,但我想他们可以称之为“设计意图”/“功能”。
  • 此 iOS 11.0 和 11.1 错误已在 iOS 11.2 中修复。
【解决方案2】:

特别是在 iOS 11.0 和 11.1 中(不在 11.2+ 之后,不在 10.x 之前),来自 UITextViewDelegate 的 textView(_:shouldInteractWith:in:interaction) 是通过与 UILongPressGestureRecognizer 而不是 UITapGestureRecognizer 的交互调用的。

对于这两个 iOS 版本,用户需要 小延迟长按 而不是 点击 来与 UITextView 链接进行本机交互。

如果对于这两个 iOS 版本根本没有调用回调,即使长按,您也可能通过继承 UITextView 并覆盖 gestureRecognizerShouldBegin(_) 来弄乱手势识别器在不应该的时候返回false

这里是gestureRecognizerShouldBegin(_) 的快速部分解决方法的示例,它将禁用 放大镜/放大镜 长按(如果这是覆盖的所需意图),但仍然允许长按链接:

override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
    if gestureRecognizer is UIPanGestureRecognizer {
        // required for compatibility with isScrollEnabled
        return super.gestureRecognizerShouldBegin(gestureRecognizer)
    }
    if let tapGestureRecognizer = gestureRecognizer as? UITapGestureRecognizer,
        tapGestureRecognizer.numberOfTapsRequired == 1 {
        // allowing taps for links
        return super.gestureRecognizerShouldBegin(gestureRecognizer)
    }
    if let longPressGestureRecognizer = gestureRecognizer as? UILongPressGestureRecognizer,
        // allowing small delay long press for links (required for iOS 11.0-11.1)
        // average comparison value is used to distinguish between:
        // 0.12 (smallDelayRecognizer)
        // 0.5 (textSelectionForce and textLoupe)
        longPressGestureRecognizer.minimumPressDuration < 0.325 {
        return super.gestureRecognizerShouldBegin(gestureRecognizer)
    }
    gestureRecognizer.isEnabled = false
    return false
}

另一种方法是完全禁止UILongPressGestureRecognizerUITapGestureRecognizer,除了你自己构建的用于与链接交互的自制UITapGestureRecognizer。

【讨论】:

    猜你喜欢
    • 2015-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-11
    • 1970-01-01
    • 1970-01-01
    • 2014-04-18
    • 2016-03-29
    相关资源
    最近更新 更多