How to get an “unselect" notification on UILabel

I have a UILabel and I need it to support copy & paste copy (actually only copy as it is read-only). I have subclassed UILabel for copy support, and it works great. I also added a selection of text, so that the user knows what exactly he copies when he clicks on the label.

My problem is that I do not know how to deselect this when the user clicks elsewhere. The copy bubble disappears, but I don't get any callback, so the text remains selected. Is there any special feedback that I missed that I can use, or do I need to come up with some kind of dirty hack? Or maybe there is a more standard way to select text in UILabel, that I don’t know that it will be processed automatically, like copying a bubble?

Here is my custom UILabel code:

- (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);
    }
}

Any help appreciated!

+3
source share
1 answer

Personally, I would use a UITextView with the ability to edit for NO.

, , ( ), UILabel .

override - (UIView *) hitTest: (CGPoint) point withEvent: (UIEvent *) ;

UILabel, NSNotification, UILabel, .

, touchsCanceled !

+2

Source: https://habr.com/ru/post/1768621/


All Articles