【问题标题】:Tap Gesture on TextView and its super view does not work in iOS 11在 TextView 上点击 Gesture,其超级视图在 iOS 11 中不起作用
【发布时间】:2018-02-26 07:46:46
【问题描述】:

我有一个类似 View 1 的视图,它有一个 UITextView 的子视图。

我必须在我的文本视图中启用链接和日期事件,为此我启用了用户交互。但是我需要对其超级视图进行一些点击处理,即 View 1 ,所以我在超级视图上也启用了点击手势。

使用此设置,我将在文本视图中进行链接检测和处理,如果我没有点击链接,则点击手势将自行传递到超级视图。但是在 iOS 11 中,这似乎被打破了,我似乎永远无法将点击手势传递给超级视图。有人可以帮我在 iOS 11 上恢复与以前版本相同的行为吗?

我写的代码是这样的-

  [V addSubView:tv];
  [tv setFrame:[self calculateFrameForTextView]];
  [tv setUserInteractionEnabled:YES];
  [tv setEditable:NO];
  [tv setSelectable:YES];
  [tv setDataDetectorTypes:UIDataDetectorTypeAll];

  UITapGestureRecognizer *tap= [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doSomething)];
  [V addGestureRecognizer:tap];


   ............................
   |    UIView (V)             |
   |                           |
   |   |-------------------|   |
   |   |  UITextView  (tv) |   |
   |   |...................|   |
   .............................

如果我点击文本视图上不是链接/其他数据检测器类型的任何内容,我希望将“doSomething”称为通过点击超级视图注册的选择器。此行为在 版本中有效

【问题讨论】:

  • 显示您的代码,以便更好地理解!
  • @PratikPrajapati 确实添加了代码和视图结构

标签: ios uitextview ios11 uitapgesturerecognizer


【解决方案1】:

我终于找到了一种从文本视图中检测触摸的解决方案,适用于 iOS 11。尚未在早期版本上进行测试。
点击链接或附件不会触发关闭。

/// Provide a callback when single tapping on a non-attachment area
@IBDesignable class UITextViewFixed: UITextView {

    var didTappedOnAreaBesidesAttachment: (() -> ())? = nil

    // A single tap won't move.
    private var isTouchMoved = false

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesMoved(touches, with: event)

        isTouchMoved = true
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesEnded(touches, with: event)

        if !isTouchMoved &&
            !isTapOnAttachment(touches.first!.location(in: self)) &&
            selectedRange.length == 0 {
            didTappedOnAreaBesidesAttachment?()
        }

        isTouchMoved = false
    }

    override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesCancelled(touches, with: event)

        // `UITextView` will cancel the touch then starting selection

        isTouchMoved = false
    }

    private func isTapOnAttachment(_ point: CGPoint) -> Bool {
        let range = NSRange(location: 0, length: attributedText.length)
        var found = false
        attributedText.enumerateAttribute(.attachment, in: range, options: []) { (value, effectiveRange, stop) in
            guard value is NSTextAttachment else {
                return
            }
            let rect = layoutManager.boundingRect(forGlyphRange: effectiveRange, in: textContainer)
            if rect.contains(point) {
                found = true
                stop.pointee = true
            }
        }
        return found
    }
}

【讨论】:

    猜你喜欢
    • 2014-04-16
    • 1970-01-01
    • 1970-01-01
    • 2018-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多