UIMenuController不显示

我正在尝试创build一个自定义的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]; 

没有错误或exception,但菜单控制器不显示。

你需要做三件事情:

  1. 您需要在视图或视图控制器上调用-becomeFirstResponder
  2. 您的视图或视图控制器需要实现-canBecomeFirstResponder (返回YES )。
  3. 或者,您的视图或视图控制器可以实现-canPerformAction:action withSender:sender以独立的方式显示/隐藏菜单项。

只有当视图是第一个响应者时, UIMenuController才在任何视图中可见

- (BOOL)canPerformAction方法返回YES

因此,如果你的菜单控制器被显示在button上,button动作的第一行应该是[self becomeFirstResponder] 。 注意:这里的自我是将呈现菜单的视图。

如果你的菜单要长按手势显示,那么在写之前将longPressGesture添加到UIView和longpress事件中

 [menuController setTargetRect:CGRectMake(50.0, 50.0, 0, 0) inView:self.view]; [menuController setMenuVisible:YES animated:YES]; 

[self becomeFirstResponder];

然后按照OZ提到的步骤。

答案提到了三件事,但要挑剔,有六件事:

  1. 菜单处理程序必须是UIView。 如果不是, -becomeFirstResponder失败。
  2. 菜单处理程序必须具有userInteractionEnabled = YES
  3. 菜单处理程序必须位于视图层次结构中,其-window属性必须与inView:参数中视图的窗口相同。
  4. 你需要实现-canBecomeFirstResponder并返回YES
  5. 在调用[handler becomeFirstResponder] [menu setTargetRect:inView:] 之前 ,您需要调用[handler becomeFirstResponder] ,否则后者将失败。
  6. 你需要调用[menu setTargetRect:inView] (至less一次)和[menu setMenuVisible:animated:]

特别是上面的1-3点给了我。 我想要一个自定义的菜单处理程序类,一开始是一个UIResponder ,这导致-becomeFirstResponder返回NO ; 那么它是一个UIView ,失败了,然后我试图使它成为一个工作的UIButton ,但只是因为userInteractionEnabled默认为YESUIViewNO

下面是一个完整的评论工作示例…

查看子类头文件

 #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中单独返回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; } 

如果你想知道所有的行动,那么

访问链接

为了防止任何人使用iOS6特别(随机)出现此问题,您可能需要查看与在设备上启用“说话select”(设置 – >常规 – >辅助function – >说话select:开启)相关的SO 。 less数我的用户无法看到自定义的UIMenuItems ,这是原因。

在Swift 3.0中 –

在我的情况下,我想让VC预先selectTextView中的文本,并显示一个自定义菜单供用户对该select采取行动。 正如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中,当用户点击一个button时:

 @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 } } } 

也许是因为CGRectMake(50.0, 50.0, 0, 0)创build了一个width = 0height = 0CGRect

欢呼,又名