2011-12-05 53 views
7

我正在制作一个类似于手机上的Messages应用程序的iphone应用程序。我只是设置了通过UIMenuController复制邮件的功能,但是如果键盘显示并且有人试图复制邮件,键盘就会消失(大概是因为我的[cell becomeFirstResponder];,其中cell是被复制的邮件单元格)。显示UIMenuController丢失键盘

有没有办法显示复制信息而不会丢失键盘?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: 
(NSIndexPath *)indexPath { 

    //...other cell setup stuff... 

    UILongPressGestureRecognizer *longPressGesture = 
    [[UILongPressGestureRecognizer alloc] 
     initWithTarget:self action:@selector(showCopyDialog:)]; 
    [cell addGestureRecognizer:longPressGesture]; 

    return cell; 
} 

- (void)showCopyDialog:(UILongPressGestureRecognizer *)gesture 
{ 
    if (gesture.state == UIGestureRecognizerStateBegan) 
    { 
     ConvoMessageCell *cell = (ConvoMessageCell *)[gesture view]; 
     NSIndexPath *indexPath = [self.tblConvo indexPathForCell:cell]; 

     UIMenuController *theMenu = [UIMenuController sharedMenuController]; 
     [cell becomeFirstResponder]; 
     [theMenu setTargetRect:CGRectMake(menuX, menuY, 100, 100) inView:cell]; 
     [theMenu setMenuVisible:YES animated:YES];   
    } 
} 

回答

7

在iOS 5中,您现在可以使用表视图委托方法来显示菜单控制器:

- (BOOL) tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath 

- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender; 

- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender; 

显示菜单控制器以这种方式不会辞职的键盘。

我仍然对此感到好奇,因为我有一个应用程序支持iOS 5以前的版本,我希望按照您所说的操作(当复制菜单出现时不会退出键盘)。

+0

这可能工作,但MenuController将被放置在单元格的水平中心。 –

16

我通过继承的UITextView提供一种方式来覆盖nextResponder和禁用内置的动作(粘贴)解决了这个难题,就像这样:

@interface CustomResponderTextView : UITextView 

@property (nonatomic, weak) UIResponder *overrideNextResponder; 

@end 

@implementation CustomResponderTextView 

@synthesize overrideNextResponder; 

- (UIResponder *)nextResponder { 
    if (overrideNextResponder != nil) 
     return overrideNextResponder; 
    else 
     return [super nextResponder]; 
} 

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender { 
    if (overrideNextResponder != nil) 
     return NO; 
    else 
     return [super canPerformAction:action withSender:sender]; 
} 

@end 

然后,在你手势动作处理程序,检查文本视图是否已经是第一响应者。如果是这样,是否覆盖下一个响应者;否则键盘可能隐藏无论如何,你可以简单地becomeFirstResponder。您还可以重置覆盖当菜单隐藏:

if ([inputView isFirstResponder]) { 
    inputView.overrideNextResponder = self; 
    [[NSNotificationCenter defaultCenter] addObserver:self 
     selector:@selector(menuDidHide:) 
     name:UIMenuControllerDidHideMenuNotification object:nil]; 
} else { 
    [self becomeFirstResponder]; 
} 

- (void)menuDidHide:(NSNotification*)notification { 

    inputView.overrideNextResponder = nil; 
    [[NSNotificationCenter defaultCenter] removeObserver:self 
     name:UIMenuControllerDidHideMenuNotification object:nil]; 
} 

使用iOS 5中(shouldShowMenuForRowAtIndexPath等)推出的表视图委托方法是不是一个解决方案,我,我需要控制定位(默认情况下,它只是简单地在单元格中水平居中,但是我正在显示消息气泡,并希望菜单居中在实际气泡上)。

+0

很好的答案,谢谢!任何参考书目? – AmitP

+0

这部分工作。显示的MenuController属于CustomResponderTextView而不属于单元格。任何想法来解决这个问题? –