UIMenuController not showing up
The below is a full commented working example ...
View subclass header file
#import <Foundation/Foundation.h>
@interface MenuControllerSupportingView : UIView
{
}
@end
View subclass source file
#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;
}
view Controller header file
#import <UIKit/UIKit.h>
@interface ViewController1 : UIViewController
@end
view Controller source file
#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
In View class if u write return YES alone in canPerformAction you will see all the default menuitems like camera symbol,cut,copy etc..
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
return YES;
}
if u want to show something like camera alone then
-(BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if(action==@selector(_insertImage:))
return YES;
else
return NO;
}
if u want to know about all the actions then
visit the link
The answer mentions three things, but to be picky, there are six:
- The menu handler must be a UIView. If it isn't,
-becomeFirstResponder
fails. - The menu handler must have
userInteractionEnabled = YES
- The menu handler must be in the view hierarchy and its
-window
property must be the same as the window for the view in theinView:
argument. - You need to implement
-canBecomeFirstResponder
and returnYES
. - You need to call
[handler becomeFirstResponder]
, before[menu setTargetRect:inView:]
is called, or the latter will fail. - You need to call
[menu setTargetRect:inView]
(at least once) and[menu setMenuVisible:animated:]
.
In particular points 1-3 above got me. I wanted a custom menu handler class that was a UIResponder
at first, which caused -becomeFirstResponder
to return NO
; then it was a UIView
, which failed, then I tried making it a UIButton
which worked, but only because userInteractionEnabled
defaults to YES
for buttons and NO
for UIView
s.
UIMenuController
is visible on any view only if the view is first responder and
- (BOOL)canPerformAction
method returns YES
Hence if your menu controller is to be shown on button click, the first line in the button action should be [self becomeFirstResponder]
. NOTE: here self is the view which will present the menus.
If your menus are to be shown on long press gesture, then add longPressGesture to the UIView
and in the longpress event before writing
[menuController setTargetRect:CGRectMake(50.0, 50.0, 0, 0) inView:self.view];
[menuController setMenuVisible:YES animated:YES];
write [self becomeFirstResponder];
Then follow the steps mentioned by OZ.
You need to do three things:
- You need to call
-becomeFirstResponder
on the view or view controller. - Your view or view controller needs to implement
-canBecomeFirstResponder
(returningYES
). - Optionally, your view or view controller can implement
-canPerformAction:action withSender:sender
to show/hide menu items on an individual basis.