我正在尝试创建自定义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];
没有错误或异常,但菜单控制器只是没有显示。
答案 0 :(得分:154)
你需要做三件事:
-becomeFirstResponder
。-canBecomeFirstResponder
(返回YES
)。-canPerformAction:action withSender:sender
以单独显示/隐藏菜单项。答案 1 :(得分:18)
答案提到三件事,但要挑剔,有六件事:
-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。
答案 2 :(得分:15)
UIMenuController
在任何视图中都可见
- (BOOL)canPerformAction
方法返回YES
因此,如果要在按钮单击时显示菜单控制器,则按钮操作中的第一行应为[self becomeFirstResponder]
。注意:这里的self是显示菜单的视图。
如果要在长按手势上显示菜单,请在写入之前将longPressGesture添加到UIView
和longpress事件中
[menuController setTargetRect:CGRectMake(50.0, 50.0, 0, 0) inView:self.view];
[menuController setMenuVisible:YES animated:YES];
写[self becomeFirstResponder];
然后按照OZ提到的步骤进行操作。
答案 3 :(得分:5)
下面是一个完整的评论工作示例......
查看子类头文件
#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;
}
如果您想了解所有行动,那么
访问link
答案 4 :(得分:2)
万一有人在iOS6中专门(随机)解决此问题:您可能希望查看与在设备上启用了语音选择相关的this SO(设置 - &gt;常规 - &gt;辅助功能 - &gt;说出选择:开)。我的少数用户无法看到自定义UIMenuItems
,这就是原因。
答案 5 :(得分:1)
在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
}
}
}
答案 6 :(得分:-1)
可能是因为CGRectMake(50.0, 50.0, 0, 0)
使用CGRect
和width = 0
创建了height = 0
?
欢呼声, ANKA