2010-06-24 125 views
55

我想創建一個自定義的UIMenuController並在我的視圖中顯示它。這裏是我的代碼: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]; 

沒有錯誤或異常,但菜單控制器不顯示。

回答

142

你需要做三件事情:

  1. 你需要調用視圖或視圖控制器-becomeFirstResponder
  2. 您的視圖或視圖控制器需要執行-canBecomeFirstResponder(返回YES)。
  3. (可選)您的視圖或視圖控制器可以實現-canPerformAction:action withSender:sender以獨立顯示/隱藏菜單項。
+2

樂於助人,非常有幫助。 – Jake 2011-09-06 15:03:06

+0

這在MonoTouch中的效果非常好 - 只有要注意的事情是'CanBecomeFirstResponder'是一個屬性重寫,並且您必須爲'UIMenuController.MenuItems'屬性指定一個'UIMenuItem []'數組。 – PaulJ 2012-05-10 08:45:58

+4

當我在視圖*上調用'becomeFirstResponder' *時沒有工作。在控制器上調用它工作得很好。 – 2013-04-15 17:02:26

-1

可能是因爲CGRectMake(50.0, 50.0, 0, 0)創建了一個CGRectwidth = 0height = 0

歡呼聲, 安卡

+0

即使我將寬度/高度設置爲100,仍然不顯示。 – indragie 2010-06-24 19:22:29

+0

好吧,你可以嘗試添加方法(BOOL)canPerformAction:(SEL)action withSender:(id)sender並返回YES。 – anka 2010-06-24 19:37:45

+0

仍然無法使用。 – indragie 2010-06-24 19:50:07

15

UIMenuController是僅如果視圖是第一響應和

任何視圖中可見

- (BOOL)canPerformAction方法返回YES

因此,如果您的菜單控制器是上按鈕點擊被顯示,在該第一線按鈕操作應該是[self becomeFirstResponder]。注意:這裏的自我是將呈現菜單的視圖。

如果你的菜單上長按手勢顯示,然後寫

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

[self becomeFirstResponder];

然後遵循OZ提到的步驟前添加longPressGesture到UIView,並在長按事件。

+0

我試過這個,但它不適合我。由於評論有限制我創建了另一個問題http://stackoverflow.com/questions/16054050/uimenucontroller-not-getting-displayed – JiteshW 2013-04-17 07:33:43

+0

謝謝,targetRect爲我做了詭計。奇怪,因爲我有另一個幾乎完全相同的類,沒有它就可以正常工作。 – Kalle 2013-08-09 12:05:55

2

爲了防止任何人在使用iOS6時特別(和隨機)出現此問題:您可能需要查看this SO與設備上啓用「說話選擇」(設置 - >常規 - >輔助功能 - >說話選擇:開)。少數我的用戶無法看到自定義UIMenuItems,這是原因。

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類如果u寫canPerformAction是獨自返回你會看到所有默認的菜單項類似相機的象徵,剪切,複製等。

-(BOOL)canPerformAction:(SEL)action withSender:(id)sender 
{ 
return YES; 
} 

如果u想獨自顯示類似相機然後

-(BOOL)canPerformAction:(SEL)action withSender:(id)sender 
{ 
if([email protected](_insertImage:)) 
    return YES; 
else 
    return NO; 

} 

如果u想知道,那麼所有的行動

參觀link

13

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

  1. 菜單處理程序必須是一個UIView。如果不是,則-becomeFirstResponder失敗。
  2. 的菜單句柄必須userInteractionEnabled = YES
  3. 菜單處理程序必須在視圖層次及其-window屬性必須是一樣的窗口中inView:爭論的觀點。
  4. 您需要執行-canBecomeFirstResponder並返回YES
  5. 您需要致電[handler becomeFirstResponder],[menu setTargetRect:inView:]被調用,否則後者將失敗。
  6. 您需要致電[menu setTargetRect:inView](至少一次)和[menu setMenuVisible:animated:]

特別是上面的1-3點讓我受不了。我想要一個自定義菜單處理程序類,最初是UIResponder,這導致-becomeFirstResponder返回NO;那麼它是一個UIView,它失敗了,然後我試圖使它成爲UIButton工作,但只是因爲userInteractionEnabled默認爲YES按鈕和NOUIView s。

+1

這應該是公認的答案。 – Grimxn 2017-03-24 19:03:56

0

在雨燕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 
    } 
    } 
}