UIMenuController 没有出现
Posted
技术标签:
【中文标题】UIMenuController 没有出现【英文标题】:UIMenuController not showing up 【发布时间】:2010-06-24 18:38:54 【问题描述】:我正在尝试创建一个自定义 UIMenuController 并将其显示在我的视图中。这是我的代码:
UIMenuController *menuController = [UIMenuController sharedMenuController];
UIMenuItem *listMenuItem = [[UIMenuItem alloc] initWithTitle:@"List" action:@selector(addList:)];
[menuController setMenuItems:[NSArray arrayWithObject:listMenuItem]];
[menuController setTargetRect:CGRectMake(50.0, 50.0, 0, 0) inView:self.view];
[menuController setMenuVisible:YES animated:YES];
[listMenuItem release];
没有错误或异常,但菜单控制器没有显示。
【问题讨论】:
【参考方案1】:你需要做三件事:
-
您需要在视图或视图控制器上调用
-becomeFirstResponder
。
您的视图或视图控制器需要实现-canBecomeFirstResponder
(返回YES
)。
(可选)您的视图或视图控制器可以实现 -canPerformAction:action withSender:sender
以单独显示/隐藏菜单项。
【讨论】:
这在 MonoTouch 中也非常有效——唯一需要注意的是CanBecomeFirstResponder
是一个属性覆盖,您必须将 UIMenuItem[]
数组分配给 UIMenuController.MenuItems
属性.
当我打电话给becomeFirstResponder
视图时不起作用。在控制器上调用它工作正常。
为了确保对 becomeFirstResponder 的调用成功,您可以检查它返回的 BOOL 是否为 YES。否则你可以期待 UIMenuController 的展示会失败。
只要我实施了第 3 步(非可选),我就可以在 view 上进行这项工作。
实施`-canPerformAction`不是可选的。【参考方案2】:
答案提到了三件事,但要挑剔的话,有六件事:
-
菜单处理程序必须是 UIView。如果不是,
-becomeFirstResponder
会失败。
菜单处理程序必须有userInteractionEnabled = YES
菜单处理程序必须位于视图层次结构中,并且其-window
属性必须与inView:
参数中的视图窗口相同。
你需要实现-canBecomeFirstResponder
并返回YES
。
你需要调用[handler becomeFirstResponder]
,之前[menu setTargetRect:inView:]
被调用,否则会失败。
您需要致电[menu setTargetRect:inView]
(至少一次)和[menu setMenuVisible:animated:]
。
特别是上面的第 1-3 点让我明白了。我想要一个自定义菜单处理程序类,最初是 UIResponder
,这导致 -becomeFirstResponder
返回 NO
;然后是UIView
,但失败了,然后我尝试将其设置为UIButton
,但这只是因为userInteractionEnabled
默认为YES
用于按钮,NO
用于UIView
s。
【讨论】:
【参考方案3】:UIMenuController
仅在视图是第一响应者且任何视图上可见
- (BOOL)canPerformAction
方法返回YES
因此,如果要在单击按钮时显示菜单控制器,则按钮操作中的第一行应为 [self becomeFirstResponder]
。注意:这里 self 是显示菜单的视图。
如果您的菜单要在长按手势上显示,则在写入之前将 longPressGesture 添加到UIView
和长按事件中
[menuController setTargetRect:CGRectMake(50.0, 50.0, 0, 0) inView:self.view];
[menuController setMenuVisible:YES animated:YES];
写[self becomeFirstResponder];
然后按照OZ提到的步骤进行。
【讨论】:
我试过了,但它不适合我。由于评论有限制,我创建了另一个问题***.com/questions/16054050/… 谢谢,targetRect 帮了我大忙。很奇怪,因为我还有另一个几乎相同的类,没有它也能正常工作。【参考方案4】:下面是一个完整的注释工作示例...
查看子类头文件
#import <Foundation/Foundation.h>
@interface MenuControllerSupportingView : UIView
@end
查看子类源文件
#import "MenuControllerSupportingView.h"
@implementation MenuControllerSupportingView
//It's mandatory and it has to return YES then only u can show menu items..
-(BOOL)canBecomeFirstResponder
return YES;
-(void)MenuItemAClicked
NSLog(@"Menu item A clicked");
-(void)MenuItemBClicked
NSLog(@"Menu item B clicked");
-(void)MenuItemCClicked
NSLog(@"Menu item C clicked");
//It's not mandatory for custom menu items
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender
if(action == @selector(MenuItemAClicked))
return YES;
else if(action == @selector(MenuItemBClicked))
return YES;
else if(action == @selector(MenuItemCClicked))
return YES;
else
return NO;
查看控制器头文件
#import <UIKit/UIKit.h>
@interface ViewController1 : UIViewController
@end
查看控制器源文件
#import "ViewController1.h"
#import "MenuControllerSupportingView.h"
@interface ViewController1 ()
MenuControllerSupportingView *vu;
@end
@implementation ViewController1
- (void)viewDidLoad
[super viewDidLoad];
vu=[[SGGI_MenuControllerSupportingView alloc]initWithFrame:CGRectMake(0,0,768,1024)];
[self.view addSubview:vu];
UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom];
[btn setFrame:CGRectMake(200,200,200,30)];
[btn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[btn setTitle:@"Show" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(SHowMenu) forControlEvents:UIControlEventTouchUpInside];
[vu addSubview:btn];
-(void)SHowMenu
UIMenuController *menucontroller=[UIMenuController sharedMenuController];
UIMenuItem *MenuitemA=[[UIMenuItem alloc] initWithTitle:@"A" action:@selector(MenuItemAClicked)];
UIMenuItem *MenuitemB=[[UIMenuItem alloc] initWithTitle:@"B" action:@selector(MenuItemBClicked)];
UIMenuItem *MenuitemC=[[UIMenuItem alloc] initWithTitle:@"C" action:@selector(MenuItemCClicked)];
[menucontroller setMenuItems:[NSArray arrayWithObjects:MenuitemA,MenuitemB,MenuitemC,nil]];
//It's mandatory
[vu becomeFirstResponder];
//It's also mandatory ...remeber we've added a mehod on view class
if([vu canBecomeFirstResponder])
[menucontroller setTargetRect:CGRectMake(10,10, 0, 200) inView:vu];
[menucontroller setMenuVisible:YES animated:YES];
-(void)didReceiveMemoryWarning
[super didReceiveMemoryWarning];
@end
在 View 类中,如果你在 canPerformAction 中单独编写 return YES,你将看到所有默认菜单项,如相机符号、剪切、复制等。
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender
return YES;
如果你想单独展示像相机这样的东西
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender
if(action==@selector(_insertImage:))
return YES;
else
return NO;
如果你想知道所有的动作然后
访问link
【讨论】:
非常有帮助,我在 swift 中添加了类似的代码来子类化 UIButton,并且像魔术一样工作。谢谢。【参考方案5】:以防万一任何人在 ios6 中特别(随机)遇到此问题:您可能想查看与在设备上启用“朗读选择”相关的this SO(设置 -> 常规 -> 辅助功能 -> 朗读选择:在)。我的少数用户无法看到自定义 UIMenuItems
,这就是原因。
【讨论】:
【参考方案6】:在 Swift 3.0 中 -
在我的例子中,我想让 VC 预先选择 TextView 中的文本,并显示一个自定义菜单供用户对该选择执行操作。正如 Kalle 所提到的,顺序非常重要,尤其是将setMenuVisible
放在最后。
在 VC 中,viewDidLoad
:
menuCont = UIMenuController.shared
let menuItem1: UIMenuItem = UIMenuItem(title: "Text", action: #selector(rtfView.textItem(_:)))
let menuItems: NSArray = [menuItem1]
menuCont.menuItems = menuItems as? [UIMenuItem]
在 VC 中,当用户点击按钮时:
@IBAction func pressed(_ sender: Any)
self.textView.selectedRange = NSMakeRange(rangeStart, rangeLength)
self.textView.becomeFirstResponder()
menuCont.setTargetRect(CGRect.zero, in: self.textView)
menuCont.setMenuVisible(true, animated: true)
最后,在TextView的子类中:
class rtfView: UITextView
override var canBecomeFirstResponder: Bool
return true
override func canPerformAction(_ action: Selector, withSender sender: Any!) -> Bool
if (action == #selector(textItem(_:)))
return true
else
return false
【讨论】:
【参考方案7】:可能是因为CGRectMake(50.0, 50.0, 0, 0)
用width = 0
和height = 0
创建了一个CGRect
?
干杯, 安卡
【讨论】:
即使我将宽度/高度设置为 100 之类的值,仍然不显示。 好的,你可以尝试添加方法(BOOL)canPerformAction:(SEL)action withSender:(id)sender 并返回YES。以上是关于UIMenuController 没有出现的主要内容,如果未能解决你的问题,请参考以下文章
没有显示 uitextview 的 uimenucontroller,通用应用程序 xcode 4
在 UIMenuController 出现之前更改用于 UIMenuController 的标签标题