在 UITextField 的 editingDidBegin 中显示 UIMenuController

Posted

技术标签:

【中文标题】在 UITextField 的 editingDidBegin 中显示 UIMenuController【英文标题】:Display UIMenuController in editingDidBegin of a UITextField 【发布时间】:2012-07-01 16:33:41 【问题描述】:

我只想在文本字段变为活动状态后立即显示 UIMenuController。 我现在正在做的是:

- (IBAction)textFieldeditingDidBegin:(UITextField *)sender 
    // textfield menu item
    UIMenuController *menu = [UIMenuController sharedMenuController];
    [menu setTargetRect:sender.frame inView:self.view];
    [menu setMenuVisible:YES animated:YES];

该方法被调用,但它只是不会显示菜单... 如果我在文本字段上进行触摸+按住手势,它会定期出现。

我希望有一个简单的解决方案, 谢谢

【问题讨论】:

你为sharedMenuController设置了menuItems了吗? 是的,我做了,但即使不是应该显示标准的。 您为什么使用IBAction 而不是常规委托的方法?您是否在 XIB 中手动链接操作? 因为文本字段没有委托。 您当然可以使用UITextFieldDelegate 协议为UITextField 设置委托。事实上,我的测试应用程序使用主控制器作为委托来处理来自文本字段的事件。 【参考方案1】:

我为您的问题找到了一个很好的解决方案。

当您开始使用此方法编辑文本字段时,您可以轻松地使 UIMenuController 出现:

- (void)textFieldDidBeginEditing:(UITextField *)textField

    double delayInSeconds = 0.1;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void)
        UIMenuController *menu = [UIMenuController sharedMenuController];
        [menu setTargetRect:textField.frame inView:textField.superview];
        [menu setMenuItems:[NSArray arrayWithObjects:
                            [[UIMenuItem alloc] initWithTitle:@"Test" action:@selector(test)],
                            nil]];
        [menu setMenuVisible:YES animated:YES];
    );

我使用dispatch_after 调用来确保菜单显示UITextField 上的所有默认系统调用完成后。

我还将setTargetRect:: 方法的inView:self.view 部分更改为inView:textField.superview,以确保菜单在文本字段的容器视图中正确显示。

如果您还想禁用 UITextField 的默认菜单控件,您可以将此方法添加到您的控制器:

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender

    if (action == @selector(cut:))
        return NO;
    else if (action == @selector(copy:))
        return NO;
    else if (action == @selector(paste:))
        return NO;
    else if (action == @selector(select:) || action == @selector(selectAll:))
        return NO;
    else
        return [super canPerformAction:action withSender:sender];

这在模拟器中工作得非常好。希望对您有所帮助!

【讨论】:

“虽然 UITextField 的默认控件可用,但 UIMenuController 的每个自定义都将不起作用。通过显式禁用它们,您可以在菜单控制器中显示任何您想要的内容。” -> 错了,它有效。我需要它们,所以我不会实施你的第一部分。但是第二件事听起来不错,我今天就试试。 @yinkou,很抱歉,我的测试应用程序源代码中有错字。你是对的,你可以同时拥有两个控件。主要方法工作正常:) 我更新了答案以反映这些变化。【参考方案2】:

更简单的解决方案:

- (void)textFieldDidBeginEditing:(UITextField *)textField

    [[NSOperationQueue mainQueue] addOperationWithBlock:^
        [textField select:nil];
        UIMenuController *menuController = [UIMenuController sharedMenuController];
        [menuController setMenuVisible:YES animated:YES];
    ];

【讨论】:

以上是关于在 UITextField 的 editingDidBegin 中显示 UIMenuController的主要内容,如果未能解决你的问题,请参考以下文章

在 UITextField 操作中将 UITextField 字符串转换为 Double

如果 UITextField 已经创建,不要在 Tap 上重新创建 UITextField

如果添加了新的 UITextField,如何向下移动许多 UITextField

使用未声明类型的 UITextfield

swift 具有错误文本支持的UITextField。在UITextField下面绘制错误文本。

UITextField - 在键盘和 UIPickerView 之间切换