2011-07-06 10 views
3

私はコピーメニューを提供するためにUILabelをサブクラス化しました。このメニューが表示されたときにUILabelを目立たせるような効果を加えたいと思います。UIMenucontrollerを使ったUILabelが最初のレスポンダーを外に退出しない

今は境界を追加したり削除したりしようとしています。しかし、ユーザーがラベルに触れ、ラベルの外に触れると、境界線が消えず、コピーメニューが表示されます。

NSLogを追加した後、resignfirstresponderが呼び出されていないようです。この事態が発生した場合のレスポンダーチェーンではどうなりますか、このイベントで国境をどのように消滅させることができますか?

コードを次のように

@implementation CopyLabel 

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

     NSLog(@"Resign"); 
     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]) { 
     [self resignFirstResponder]; 
    } 
    else if([self becomeFirstResponder]) { 

    } else { 
     [self resignFirstResponder]; 
    } 
} 

- (void)drawRect:(CGRect)rect { 
    [super drawRect:rect]; 
    self.layer.borderColor = [UIColor blueColor].CGColor; 
    self.layer.borderWidth = 0.0; 
    if(self.highlighted) { 
     self.layer.borderWidth = 1.0; 
    } 
} 


@end 
+0

。ロジックが実行されたら、強調表示されたプロパティを更新した後に[self setsNeedsDisplay]を追加します。 –

+0

canResignFirstResponderメソッドをオーバーライドしましたが、問題は解決しません。あなたがUILabelの中に触れた後でUILabelのどこかに触れると、それはresignFirstResponderではないようです。後でもう一度触れると(どこに触れるかメニューが消えた後)、それは最初のレスポンダーに戻ります。 – cubiclewar

+0

タッチを受け取っているビュー(ラベル表示ではありません)。あなたのビューコントローラのタッチまたは関連するイベントを傍受し、UILabelサブクラスの状態とその境界をクリーンアップする必要があります。 –

答えて

2

UIMenuController記事UIMenuControllerDidHideMenuNotification。あなたがその通知(NSNotificationCenterを使用して)を聞くとき、適切なタイミングであなたのラベルにresignFirstResponderを送ることができます。

例:

- (id)init... { 
    ... 
    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(editMenuHidden) 
               name:UIMenuControllerDidHideMenuNotification 
               object:nil]; 
    ... 
} 

- (void)dealloc { 
    ... 
    [[NSNotificationCenter defaultCenter] removeObserver:self 
               name:UIMenuControllerDidHideMenuNotification 
               object:nil]; 
    ... 
} 

- (void)editMenuHidden { 
    [self resignFirstResponder]; 
} 

... 
は(BOOL)canResignFirstResponerをオーバーライドし、その方法は、ビュー階層によって呼び出されているかどうかを確認するためにあなたの方法を変更し
関連する問題