Нажмите «Жест» в TextView, и его суперпредставление не работает в iOS 11.

У меня есть представление, в котором сделано что-то вроде этого представления 1, и оно имеет подвид UITextView.

Мне пришлось включить ссылки и события даты в моем текстовом представлении, для которых я включил взаимодействие с пользователем. Однако мне нужна некоторая обработка касания в его суперпредставлении, т.е. Вид 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» назывался селектором, зарегистрированным с помощью касания в суперпредставлении. Это поведение работало в версиях ‹ iOS11.


person New_coder    schedule 26.02.2018    source источник
comment
Покажите свой код, для лучшего понимания!   -  person Pratik Prajapati    schedule 26.02.2018
comment
@PratikPrajapati Добавил код и структуру View   -  person New_coder    schedule 27.02.2018


Ответы (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
    }
}
person kukushi    schedule 09.08.2018