Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Как получить уведомление об отмене выбора на UILabel

Автор вопроса: LopeОтветов: 1

У меня есть UILabel, и мне нужно, чтобы он поддерживал копирование и вставку (на самом деле только копирование, поскольку оно доступно только для чтения). Я создал подкласс UILabel для поддержки копирования, и он отлично работает. Я также добавил выделение текста, чтобы пользователь знал, что именно он копирует, когда нажимает на ярлык.

Моя проблема в том, что я не знаю, как отменить это выделение, когда пользователь щелкает где-то еще. Пузырь с копией исчезает, но я не получаю обратного вызова, поэтому текст остается выделенным. Есть ли специальный обратный вызов, который я пропустил, который я могу использовать, или мне нужно придумать какой-то грязный хак? Или, возможно, есть более стандартный способ выделения текста в UILabel, о котором я не знаю, который будет обрабатываться автоматически, как пузырь копирования?

Вот мой пользовательский код UILabel:

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    if(action == @selector(copy:)) {
        return YES;
    }
    else {
        return [super canPerformAction:action withSender:sender];
    }
}

- (BOOL)becomeFirstResponder {
    if([super becomeFirstResponder]) {
        self.highlighted = YES;

        UIMenuController *menu = [UIMenuController sharedMenuController];
        [menu setTargetRect:self.bounds inView:self];
        [menu setMenuVisible:YES animated:YES];

        return YES;
    }
    return NO;
}

- (BOOL)resignFirstResponder {
    if([super resignFirstResponder]) {
        self.highlighted = NO;

        UIMenuController *menu = [UIMenuController sharedMenuController];
        [menu setMenuVisible:NO animated:YES];
        [menu update];

        return true;
    }
    return false;
}

- (void)copy:(id)sender {
    UIPasteboard *board = [UIPasteboard generalPasteboard];
    [board setString:self.text];
    self.highlighted = NO;
    [self resignFirstResponder];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    if([self isFirstResponder]) {
        //UIMenuController *menu = [UIMenuController sharedMenuController];
        //[menu setMenuVisible:NO animated:YES];
        //[menu update];
        [self resignFirstResponder];
    }
    else if([self becomeFirstResponder]) {
        //UIMenuController *menu = [UIMenuController sharedMenuController];
        //[menu setTargetRect:self.bounds inView:self];
        //[menu setMenuVisible:YES animated:YES];
    }
}

- (void)setHighlighted:(BOOL)hl {
    [super setHighlighted:hl];

    [self setNeedsLayout];
}

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];

    if(self.highlighted) {
        CGContextRef ctx = UIGraphicsGetCurrentContext();
        CGContextSetRGBFillColor(ctx, 0.3, 0.8, 1.0, 0.3);
        CGContextAddRect(ctx, CGRectMake(0, 0, [self textRectForBounds:self.frame limitedToNumberOfLines:1].size.width, self.frame.size.height));
        CGContextFillPath(ctx);
    }
}

Любая помощь приветствуется!

iphoneuilabel

Ответы

Ответ 1 · рейтинг 2 · Nick H247

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

в противном случае, если вы хотите больше контроля, создайте подкласс вашего самого верхнего полноэкранного представления (или окна), дочерним элементом которого является ваш UILabel.

переопределить - (UIView *) hitTest: (CGPoint) точка withEvent: (UIEvent *) событие;

и если представление попадания не является вашим UILabel, создайте NSNotification, которое вы обрабатываете в своем подклассе UILabel, и отмените выбор.

Кстати, вы должны ВСЕГДА обрабатывать touchesCanceled также!

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы