Вызов URL-адреса не работает в TTTAttributedLabel, в то время как в его супервизоре есть UITapGestureRecognizer

В нем есть вид контейнера и UITapGestureRecognizer. И он также имеет подвид, какой тип TTTAttributedLabel.

Когда я удаляю распознаватель жестов из представления контейнера, метод делегирования TTTAttributedLabelDelegate

- (void)attributedLabel:(TTTAttributedLabel *)label didSelectLinkWithURL:(NSURL *)url can be called.

Когда я добавляю распознаватель жестов в виде контейнера. Вызывается только его метод действия. Метод делегата TTTAttributedLabelDelegate не будет вызываться.

Теперь мне нужно, чтобы метод делегата вызывался, когда я нажимаю ссылку в TTTAttributedLabel, и метод действия для вызова при нажатии на другую область представления контейнера.

Спасибо.

Ответы

Ответ 1

используйте gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch для обнаружения вашего события.

- (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
      if ([touch.view isKindOfClass:[TTTAttributedLabel class]])
      {
           return FALSE;
      }
      else
      {

         return TRUE;
      }
}

вы также можете использовать if ([touch.view isKindOfClass:[UIControl class]]) для всех UIControl, например, кнопка даже обнаруживает с помощью UIGestureRecognizer. надеюсь, что это поможет вам

Ответ 2

Я попробовал решение @Nitin, но у него есть проблема, как указал @n00bProgrammer. Кроме того, пользовательский интерфейс стал очень плохим. Мне пришлось несколько раз нажать, чтобы запустить tapGesture, который добавлен в супервизор.

Здесь у вас есть лучшее решение. TTTAttributedLabel имеет полезный метод, например, ниже.

- (BOOL)containslinkAtPoint:(CGPoint)point

Возвращает, найден ли NSTextCheckingResult в данной точке.

Итак, используйте следующий фрагмент кода, тогда только ссылка добавленная часть текста будет работать как связанная ссылка, а остальная часть области будет запускать ваш tapGesture по вашему желанию. Пользовательский опыт также превосходный.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    if ([yourTTTAttributedLabel containslinkAtPoint:[touch locationInView:yourTTTAttributedLabel]])
        return FALSE;
    else
        return TRUE;    
}

Ответ 3

Установите для свойства cancelsTouchesInView распознавателя жестов значение NO.

gestureRecognizer.cancelsTouchesInView = NO;

Ответ 4

Ответ на

@Nitin несколько правилен, если вы не хотите, чтобы жест нажатия был выполнен, если пользователь нажимает на часть вашей метки, которая не является ссылкой. Если ваш ярлык имеет текст, отличный от ссылки, я предлагаю вам сделать следующее:

  • Создайте новый метод делегата (например, handleSingleTap) в файле TTTAttributedLabel.h как @optional.

  • В TTTAttributedLabel.m найдите метод touchesEnded. Здесь у вас есть условие if (self.activeLink).

  • Создайте случай else для этого условия следующим образом:

    else {
    
        if ([self.delegate respondsToSelector:@selector(handleSingleTap)]) {
    
            [self.delegate handleSingleTap];            
        }
    }
    
  • Переопределите этот новый метод делегата в своем классе, где вы используете метку.

Таким образом, если пользователь удаляет ссылку, if выполняет обработку выбора ссылок. Если пользователь удаляет текст, отличный от ссылки, else вызовет метод в вашем классе (который является целевым методом для вашего tapGesture).

Кроме того, удалите tapGesture из вашего представления или используйте код @Nitin, чтобы НЕ обрабатывать краны на вашей метке, и пусть метка обрабатывает кран на нем.

Ответ 5

Предложение Nitin не работало для меня (не знаю почему), но это сделал:

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    if let touch = touches.first as? UITouch {
        if touch.view !== self.myTTTAttributedLabel {
            // Handle container view tap
        }
    }
    super.touchesBegan(touches, withEvent: event)
}

Вы также должны удалить распознаватель жестов из представления контейнера и обработать эти краны в if-clause выше.