Нажатие URL не работает в TTTAttributedLabel, пока в его суперпредставлении есть UITapGestureRecognizer

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

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

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

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

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

Благодарю.

5 ответов

Решение

Использовать этот 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, надеюсь, это поможет тебе

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

Здесь у вас есть лучшее решение. 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;    
}

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

gestureRecognizer.cancelsTouchesInView = NO;

@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, чтобы НЕ обрабатывать метки на ярлыке, и пусть метка обрабатывает метку самостоятельно.

вот мое решение

override func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
    if touch.view == self.lblContent {
        gr?.isEnabled = false
        return false
    }
    else {
        gr?.isEnabled = true
        return true
    }
}

gr - это жест моего представления, а lblContent(TTTAttributedLabel) - моя метка, когда я нажимаю метку, оба жеста работали одновременно (жест метки и жест просмотра), поэтому я решил эту проблему с помощью приведенного выше кода

что я пробовал до решения

cancelsTouchesInView = false
isUserInteractionEnabled = true

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

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 вместо этого.

Другие вопросы по тегам