Добавете жест с докосване към част от 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, за да изчислите низа rect.

    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