2

テキストをコピーできるように、タップで 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 通知は送信されません。

  1. 任意のラベルをタップします。
  2. ラベルが強調表示され、メニューが表示されます。
  3. 他のラベルをタップします。
  4. 前のラベルの強調表示が解除され、新しいラベルが強調表示され、メニューが表示/移動されました。
  5. ラベルの外側をタップします。メニューは削除されますが、通知は送信されません。UIMenuControllerWillHideMenu も UIMenuControllerDidHideMenu もありません。

何かアドバイス?

4

0 に答える 0