【问题标题】:Showing UIMenuController loses keyboard显示 UIMenuController 丢失键盘
【发布时间】:2011-12-05 02:25:01
【问题描述】:

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

有没有办法在不丢失键盘的情况下显示复制消息?

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

【问题讨论】:

    标签: iphone copy first-responder uimenucontroller


    【解决方案1】:

    我通过子类化 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 等)对我来说不是一个解决方案,因为我需要控制菜单的位置(默认情况下它只是水平居中于单元格上,但我'正在显示消息气泡并希望菜单位于实际气泡的中心)。

    【讨论】:

    • 很好的答案,谢谢!有这方面的参考书目吗?
    • 这部分有效。显示的 MenuController 属于 CustomResponderTextView 而不是单元格。有什么想法可以解决这个问题吗?
    【解决方案2】:

    在 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 之前的应用程序,我也想做你所说的(当复制菜单出现时不要退出键盘)。

    【讨论】:

    • 这可能有效,但 MenuController 将被放置在单元格的水平中心。
    猜你喜欢
    • 1970-01-01
    • 2019-04-11
    • 2020-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-17
    相关资源
    最近更新 更多