显示 UIMenuController 失去键盘

发布于 2024-12-19 15:27:12 字数 1140 浏览 2 评论 0原文

我正在制作一个 iPhone 应用程序,类似于手机上的消息应用程序。我刚刚设置了通过 UIMenuController 复制消息的功能,但是如果键盘显示并且有人尝试复制消息,键盘就会消失(可能是因为我的 [cell comeFirstResponder]; 其中 < code>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];        
    }
}

I'm making an iphone app similar to the Messages app that comes on the phone. I just set up the ability to copy messages via a UIMenuController, but if the keyboard is showing and someone tries to copy a message, the keyboard goes away (presumably because of my [cell becomeFirstResponder]; where cell is the message cell being copied).

Is there a way to show the Copy message without losing the keyboard?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你爱我像她 2024-12-26 15:27:12

我通过子类化 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

然后,在手势操作处理程序中,检查文本视图是否已经是第一响应者。如果是,则让它覆盖下一个响应者;否则键盘可能会被隐藏,您只需成为FirstResponder即可。当菜单隐藏时,您还必须重置覆盖:

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

I solved this dilemma by subclassing UITextView to provide a way to override the nextResponder and disable the built-in actions (Paste), like so:

@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

Then, in your gesture action handler, check whether the text view is already the first responder. If so, have it override the next responder; otherwise the keyboard is probably hidden anyway and you can simply becomeFirstResponder. You'll also have to reset the override when the menu hides:

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

Using the table view delegate methods introduced in iOS 5 (shouldShowMenuForRowAtIndexPath etc.) wasn't a solution for me as I needed control over the positioning of the menu (by default it's simply horizontally centered over the cell, but I'm displaying message bubbles and wanted the menu centered over the actual bubble).

千仐 2024-12-26 15:27:12

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

In iOS 5, you can now use the table view delegate methods to show the Menu Controller:

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

Showing the Menu Controller in this manner will not resign the keyboard.

I'm still curious about this though as I have an app that supports pre-iOS 5 that I would like to do what you're saying also (not resign the keyboard when the copy menu appears).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文