Добавьте жест касания к части UILabel

У меня есть NSAttributedString так:

NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:@"testing it out @clickhere"];
NSInteger length = str.length;
[str addAttribute:NSForegroundColorAttributeName value:[UIColor bestTextColor] range:NSMakeRange(0,length)];

NSMutableAttributedString устанавливается в UILabel следующим образом:

label.attributedText = str;

Как мне сделать жест касания (или что-то кликабельное) для другого контроллера просмотра для слов '@clickhere в строке выше?

Спасибо!


person cdub    schedule 19.01.2015    source источник
comment
Проверьте это stackoverflow.com/a/27046476/5790492.   -  person Nik Kov    schedule 29.03.2018


Ответы (4)


Я думаю, что лучший способ — добавить UIGestureRecognizer к вашему UILabel и проверить кадр, который вам нужен.

UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
[_yourLabel addGestureRecognizer:singleTap];

- (void)handleTap:(UITapGestureRecognizer *)tapRecognizer
{
    CGPoint touchPoint = [tapRecognizer locationInView: _yourLabel];

    //Modify the validFrame that you would like to enable the touch
    //or get the frame from _yourLabel using the NSMutableAttributedString, if possible
    CGRect validFrame = CGRectMake(0, 0, 300, 44);

    if(YES == CGRectContainsPoint(validFrame, touchPoint)
     {
        //Handle here.
     }
}
person Shamsudheen TK    schedule 19.01.2015

Просто сначала добавьте жест к ярлыку

[label setUserInteractionEnabled:YES];
UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
[label addGestureRecognizer:gesture];

управляйте своей областью жестов в методе ниже

- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer
{
    static CGRect touchableRect = CGRectMake(100.0f, 0.0f, 100.0f, 50.0f); // Give your rect as you need.
    CGPoint touchPoint = [gestureRecognizer locationInView:self.view];
    if (CGRectContainsPoint(touchableRect, touchPoint))
    {
       //User has tap on where you want. Do your other stuff here
    }
}
person Tapas Pal    schedule 19.01.2015

Я просто хотел бы добавить к ответу Рамшада о том, как обращаться с допустимым фреймом.

Для этого вы можете рассмотреть возможность использования UITextView вместо UILabel, который не дает вам доступа к тому, как он управляет компоновкой текста. Отключив редактирование, выделение и прокрутку, UITextView ведет себя примерно так же, как UILabel, за исключением некоторых отступов, которые необходимо удалить.

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

- (BOOL)point:(CGPoint)point touchesSomeCharacterInRange:(NSRange)range
{
    NSRange glyphRange = [self.layoutManager glyphRangeForCharacterRange:range actualCharacterRange:NULL];

    BOOL touches = NO;
    for (NSUInteger index = glyphRange.location; index < glyphRange.location + glyphRange.length; index++) {
        CGRect rectForGlyphInContainer = [self.layoutManager boundingRectForGlyphRange:NSMakeRange(index, 1) inTextContainer:self.textContainer];
        CGRect rectForGlyphInTextView = CGRectOffset(rectForGlyphInContainer, self.textContainerInset.left, self.textContainerInset.top);

        if (CGRectContainsPoint(rectForGlyphInTextView, point)) {
            touches = YES;
            break;
        }
    }

    return touches;
}

Это также будет работать для фрагмента текста, содержащего несколько слов, разбросанных по нескольким строкам из-за переноса слов. Это также будет работать с локализованными текстами, поскольку мы имеем дело с напечатанными глифами.

person Li Mengran    schedule 06.11.2015

Идея такая же, как и принятый ответ. Вот способ в Swift.

  • Предположим, вы уже настроили свой ярлык.

    youLabel.text = "please tab me!"

  • Добавьте tapGestuerRecognizer на свой ярлык

    let tap = UITapGestureRecognizer(target: self, action:    #selector(tapAction))
    yourLabel.addGestureRecognizer(tap)
    
  • Добавьте метод расширения String в String для вычисления прямоугольника строки.

    extension String {
        func rect(font: UIFont) -> CGRect {
            let label = UILabel(frame: .zero)
            label.font = font
            label.text = self
            label.sizeToFit()
            return label.frame
        }
    }
    
  • Рассчитайте доступный прямоугольник касания жеста касания.

    let pleaseStringRect = "please".rect(font: yourFont)
    let tapStringRect = "tap".rect(font: yourFont)
    let tapAreaRect = CGRect(x: pleaseStringRect.width, y:   tapStringRect.origin.y, width: tapStringRect.width, height: tapStringRect.height"
    
  • В действии делай что хочешь

     @objc private func tapAction(tap: UITapGestureRecognizer) {
       let position = tap.location(in: content)
       guard reporterFirstNameRect.contains(position) else {
           return
       }
       // Do the tap action stuff
    }
    

    Вот и все, счастливого кодирования.

person William Hu    schedule 06.03.2019