我有一个相当简单的 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 通知:
- 点击任何标签。
- 标签突出显示,菜单显示。
- 点击任何其他标签。
- 以前的标签未突出显示,新标签突出显示并且菜单显示/移动。
- 点击标签以外的任何地方。菜单已删除,但未发送任何通知。UIMenuControllerWillHideMenu 或 UIMenuControllerDidHideMenu 都不是。
有什么建议吗?