2

我有一个相当简单的 UILabel 子类,允许点击显示 UIMenuController 以便可以复制文本。在大多数情况下,这一切都很好。

#import "EPHighlightLabel.h"
#import <QuartzCore/QuartzCore.h>

@interface EPHighlightLabel()

@property (unsafe_unretained) bool hasMenuController;

@end

@implementation EPHighlightLabel

- (id)init {
    if ( (self = [super init]) ) {
        self.highlightedTextColor = [UIColor blueColor];
    }
    return self;
}

- (void)awakeFromNib {
    [super awakeFromNib];
    self.highlightedTextColor = [UIColor blueColor];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(willHideMenu)
                                                 name:UIMenuControllerWillHideMenuNotification
                                               object:nil];

    self.userInteractionEnabled = YES;
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(wasTapped:)];
    [self addGestureRecognizer:tapGesture];
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

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

- (BOOL)canBecomeFirstResponder {
    return YES;
}

- (BOOL)resignFirstResponder {
    if ([super resignFirstResponder]) {
        self.hasMenuController = false;
        self.highlighted = NO;
        return YES;
    }
    return NO;
}


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

- (void)willHideMenu {
    if (self.hasMenuController) {
        [self resignFirstResponder];
    }
}

- (IBAction)wasTapped:(id)sender {
    if([self isFirstResponder]) {
        self.hasMenuController = false;
        UIMenuController *menu = [UIMenuController sharedMenuController];
        [menu setMenuVisible:NO animated:YES];
        [menu update];
        [self resignFirstResponder];
    }
    else if([self becomeFirstResponder]) {
        self.hasMenuController = true;
        UIMenuController *menu = [UIMenuController sharedMenuController];
        [menu setMenuVisible:NO animated:YES];
        [menu setTargetRect:self.bounds inView:self];
        [menu setMenuVisible:YES animated:YES];
        self.highlighted = YES;
    }
}

@end

EPHighlightLabel在视图中,在一个本身就是子视图的 UIView 中有这三个。一切正常,您可以点击标签,文本将突出显示,然后再次点击或点击离开,菜单将被关闭并且标签不突出显示。这是通过- (void)willHideMenu调用实现的。但是在以下情况下,不会发送 UIMenuControllerWillHideMenu 通知:

  1. 点击任何标签。
  2. 标签突出显示,菜单显示。
  3. 点击任何其他标签。
  4. 以前的标签未突出显示,新标签突出显示并且菜单显示/移动。
  5. 点击标签以外的任何地方。菜单已删除,但未发送任何通知。UIMenuControllerWillHideMenu 或 UIMenuControllerDidHideMenu 都不是。

有什么建议吗?

4

0 回答 0