接连显示 UIMenuController 的问题

发布于 2024-09-09 10:53:49 字数 377 浏览 2 评论 0原文

我正在使用 UIMenuController 的新自定义功能将“复制”以外的内容添加到菜单中,以便剪切并粘贴到 Web 视图中。

我所做的就是获取对共享 UIMenuController 的引用,将 UIMenuItems 的 NSArray 设置到 menuItems 中,只要添加一个项目,一切都可以正常工作。例如我看到[COPY|FOOBAR]。

相反,如果我尝试添加多个项目,会发生什么情况,我会看到 [COPY|MORE],如果我按下 MORE 按钮,最终其他项目就会显示出来。

可以直接显示 [COPY|FOO|BAR|THREE|FOUR] 吗?我看到一些应用程序可以做到这一点,特别是 iBooks。

非常感谢任何帮助,谢谢。

干杯, 西森西奥

I'm using the new customization abilities of the UIMenuController to add things other than "Copy" to the menu for cut&paste into a webview.

What I do is getting the reference to the shared UIMenuController, setting my NSArray of UIMenuItems into the menuItems, and everything work fine as long as I add a single item. For instance I see [COPY|FOOBAR].

Instead if I try adding more than a single item, what happen is that I see [COPY|MORE], if I press into MORE than finally the other items will show up.

Is possible to show directly [COPY|FOO|BAR|THREE|FOUR] instead? I saw a few applications that are able to do this, notably iBooks.

Any help very appreaciated, thank you.

Cheers,
sissensio

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

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

发布评论

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

评论(4

无边思念无边月 2024-09-16 10:53:49

FluXa的答案实际上是正确的,但我认为它不是很清楚。

问题是,当将自定义 UIMenuItem 对象添加到共享菜单控制器 ([UIMenuController sharedMenuController]) 时,只有第一个自定义 UIMenuItem 将在菜单的初始显示上显示。如果用户点击“更多...”,将显示剩余的自定义菜单项。

但是,如果菜单不包含任何内置系统菜单项(复制:、粘贴:等),则初始菜单显示将显示所有自定义菜单项,并且不显示“更多...”项。< /em>

如果您需要包含内置系统项目,只需添加具有相同标题但具有不同选择器的自定义 UIMenuItems 即可。 ( myCopy: 与 copy: )

本质上它归结为不调用 canPerformAction:withSender: 的默认实现,显式处理所有自定义菜单项,并为所有其他(系统提供的)菜单项返回 NO:

- (BOOL) canPerformAction:(SEL)action withSender:(id)sender
{
    if ( action == @selector( onCommand1: ) )
    {
        // logic for showing/hiding command1
        BOOL show = ...;
        return show;
    }

    if ( action == @selector( onCommand2: ) )
    {
        // logic for showing/hiding command2
        BOOL show = ...;
        return show;
    }

    if ( action == @selector( onCopy: ) )
    {
        // always show our custom "copy" command
        return YES;
    }   

    return NO;
}

fluXa's answer is actually correct, but I dont think it was very clear.

The issue is that when adding custom UIMenuItem objects to the shared menu controller ([UIMenuController sharedMenuController]), only the first custom UIMenuItem will be shown on the initial display of the menu. The remaining custom menu items will be shown if the user taps "More...".

However, if the menu doesn't include any built-in system menu items (copy:, paste:, etc), the initial menu display will show all custom menu items and no "More..." item.

If you need to include the built-in system items, simply add custom UIMenuItems having the same title but with a different selector. ( myCopy: vs. copy: )

Essentially it boils down to NOT calling the default implementation of canPerformAction:withSender:, explicitly handling all custom menu items, and returning NO for all other (system-supplied) menu items:

- (BOOL) canPerformAction:(SEL)action withSender:(id)sender
{
    if ( action == @selector( onCommand1: ) )
    {
        // logic for showing/hiding command1
        BOOL show = ...;
        return show;
    }

    if ( action == @selector( onCommand2: ) )
    {
        // logic for showing/hiding command2
        BOOL show = ...;
        return show;
    }

    if ( action == @selector( onCopy: ) )
    {
        // always show our custom "copy" command
        return YES;
    }   

    return NO;
}
木落 2024-09-16 10:53:49

当我尝试在 iPad 上开发应用程序时,我们实际上遇到了同样的问题。但我所做的是禁用了弹出菜单项

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

使用

if ( [UIMenuController
共享菜单控制器] ) {
[UI菜单控制器
共享菜单控制器].menuVisible =
不; } 返回否;

然后我使用了 UIPopoverController。

问候,
扎尔兹·布兹

we have the same problem actually when i tried to develop an application in iPad. But what i did is i disabled the popup menu items in

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

Using

if ( [UIMenuController
sharedMenuController] ) {
[UIMenuController
sharedMenuController].menuVisible =
NO; } return NO;

Then i used a UIPopoverController.

Regards,
ZaldzBugz

星光不落少年眉 2024-09-16 10:53:49

遇到了同样的问题,我所做的就是用子类覆盖 webview(是的,我知道你不应该),并为 copy: 选择器的 canPerformAction: 返回 NO。然后我将自己的 Copy 项目添加到 ShareMenuController 中,该控制器从 UIWebview 调用原始方法。这样,您可以添加任意数量的项目,并且最初都是可见的。

Ran into the same problem and what I did was override the webview with a subclass (yep I know you shouldn't) and return NO for canPerformAction: for the copy: selector. Then I added my own Copy item to the ShareMenuController that calls the original method from UIWebview. That way as many items as you want can be added and are initially visible.

风透绣罗衣 2024-09-16 10:53:49

您可以使用 menuFrame (只读属性)获取先前显示的 UIMenuController 的矩形,使用它您可以计算另一个 UIMenuController 在同一位置显示的位置。

在要显示第二个 UIMenuController 的操作方法中,获取前一个 UIMenuController 的框架

在此处输入图像描述

CGRect previousRect = [[UIMenuController sharedMenuController] menuFrame];

CGRect newRect = CGRectMake(previousRect.origin.x + previousRect.size.width/2,   previousRect.origin.y + previousRect.size.height, 0, 0);

大致你会得到箭头的位置。
现在显示第二个 UIMenuController

UIMenuItem *testMenuItem1 = [[UIMenuItem alloc] initWithTitle:@"test1" action:@selector(test1ItemClicked)];
UIMenuItem *testMenuItem2 = [[UIMenuItem alloc] initWithTitle:@"test2" action:@selector(test2ItemClicked)];


[[UIMenuController sharedMenuController] setMenuItems:@[testMenuItem1,testMenuItem2]];

UIMenuController *menuController = [UIMenuController sharedMenuController];

[menuController setTargetRect:newRect inView:_readerWebView];

[menuController setMenuVisible:YES animated:YES];

在此处输入图像描述

因为 UIMenuController 是一个单例,如果你想显示以前的 menuItems,再次你必须设置它们。

you can get the rect of the previously displayed UIMenuController using menuFrame (readonly property), using that you can calculate the position for another UIMenuController to be shown at the same place.

In the action method where you are about to show the second UIMenuController, get the frame of the previous UIMenuController

enter image description here

CGRect previousRect = [[UIMenuController sharedMenuController] menuFrame];

CGRect newRect = CGRectMake(previousRect.origin.x + previousRect.size.width/2,   previousRect.origin.y + previousRect.size.height, 0, 0);

Roughly you will get the arrow position.
Now show the second UIMenuController

UIMenuItem *testMenuItem1 = [[UIMenuItem alloc] initWithTitle:@"test1" action:@selector(test1ItemClicked)];
UIMenuItem *testMenuItem2 = [[UIMenuItem alloc] initWithTitle:@"test2" action:@selector(test2ItemClicked)];


[[UIMenuController sharedMenuController] setMenuItems:@[testMenuItem1,testMenuItem2]];

UIMenuController *menuController = [UIMenuController sharedMenuController];

[menuController setTargetRect:newRect inView:_readerWebView];

[menuController setMenuVisible:YES animated:YES];

enter image description here

since UIMenuController is a singleton, if you want to show the previous menuItems, again you have to set them.

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