テキストをコピーできるように、タップで UIMenuController を表示できるようにする UILabel のかなり単純なサブクラスがあります。これは、ほとんどの状況ですべて正常に機能します。
#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 にこれらのうちの 3 つがあります。すべて正常に動作します。ラベルをタップすると、テキストが強調表示され、もう一度タップするかタップして離すと、メニューが閉じられ、ラベルの強調表示が解除されます。これは、- (void)willHideMenu
呼び出しによって実現されます。ただし、次の状況では、UIMenuControllerWillHideMenu 通知は送信されません。
- 任意のラベルをタップします。
- ラベルが強調表示され、メニューが表示されます。
- 他のラベルをタップします。
- 前のラベルの強調表示が解除され、新しいラベルが強調表示され、メニューが表示/移動されました。
- ラベルの外側をタップします。メニューは削除されますが、通知は送信されません。UIMenuControllerWillHideMenu も UIMenuControllerDidHideMenu もありません。
何かアドバイス?