uimenucontroller的使用

uimenucontroller的使用

 
标签: 

uimenu

 

it

分类: iphone开发
1. Menu所处的View必须实现 – (BOOL)canBecomeFirstResponder, 且返回YES
2. Menu所处的View必须实现 – (BOOL)canPerformAction:withSender, 并根据需求返回YES或NO
3. 使Menu所处的View成为First Responder (becomeFirstResponder)
4. 定位Menu (- setTargetRect:inView:)
5. 展示Menu (- setMenuVisible:animated:)


UIMenuController *popMenu = [UIMenuController sharedMenuController];

  

UIMenuItem *item1 = [[UIMenuItem allocinitWithTitle:@”1″action:@selector(menuItem1Pressed:)];

UIMenuItem *item2 = [[UIMenuItem allocinitWithTitle:@”2″action:@selector(menuItem2Pressed:)];

UIMenuItem *item3 = [[UIMenuItem allocinitWithTitle:@”3″action:@selector(menuItem3Pressed:)];

UIMenuItem *item4 = [[UIMenuItem allocinitWithTitle:@”4″action:@selector(menuItem4Pressed:)];

NSArray *menuItems = [NSArray arrayWithObjects:item1,item2,item3,item4,nil];

[popMenu setMenuItems:menuItems];

[popMenu setArrowDirection:UIMenuControllerArrowDown];

  

[item4 release];

[item3 release];

[item2 release];

[item1 release];

[popMenu setTargetRect:CGRectMake(162,195,0,0inView:self.dialView];

[popMenu setMenuVisible:YES animated:YES];

后来在StackOverFlow上看到这个问题,同时也在cocoachina上找到相应的方法,原来要想显示弹出菜单,必须实现3个方法,缺一不可:

 

  1. becomFirstResponder方法,使view或者viewController的self成为第一响应者,可以在相应文件的任意地方调用实现该方法,不过建议与UIMenuController放在一起。

    [self becomeFirstResponder];

  2. 设置-(BOOL) canBecomeFirstResponder的返回值为YES,原因不言而喻。

    -(BOOL) canBecomeFirstResponder{

    return YES;

    }

  3. 重载函数-(BOOL) canPerfomAction:(SEL)action withSender:(id)sender,设置要显示的菜单项,返回值为YES。若不进行任何限制,则将显示系统自带的所有菜单项(很多的,自己可以 试一下),在此,只显示自定义的4项,即:

    -(BOOL) canPerformAction:(SEL)action withSender:(id)sender{

    if (action == @selector(menuItem1Pressed:) || action ==@selector(menuItem2Pressed:) ||

    action == @selector(menuItem3Pressed:) || action ==@selector(menuItem4Pressed:)) {

    return YES;

    }

    return NO; //隐藏系统默认的菜单项

    }

    至于相应的菜单响应通过各selector函数来实现,如:

    - (IBAction) menuItem1Pressed:(id)sender{

    txtInputLabel.text = @”1″;

    [[UIMenuController sharedMenuController] setMenuVisible:NO animated:YES];

    }

    如果将系统默认的菜单也显示出来,那么自定义的菜单将作为第二菜单,调用菜单时默认显示的是第一菜单,如果要直接显示第二菜单,根据cocoachina上一位同行总结出来的经验,先设置菜单可见性为NO即可:

    [popMenu setMenuVisible:NO animated:YES];


UIMenuItem* miCustom1 = [[[UIMenuItem alloc] initWithTitle: @"MENU1"action:@selector( onCustom1: )] autorelease];
 
UIMenuItem* miCustom2 = [[[UIMenuItem alloc] initWithTitle: @"MENU2"action:@selector( onCustom2: )] autorelease];
 
UIMenuController* mc = [UIMenuController sharedMenuController];
mc.menuItems = [NSArray arrayWithObjects: miCustom1, miCustom2,nil];



 

UIMenuController使用

当苹果在 iOS 3.0 中增加了剪切、复制和粘贴功能时,它同时为开发者提供了 UIMenuController 组件用来定制该弹出菜单,但不幸的是,最开始的实现要很麻烦:
  1. 附加在菜单的视图的 canBecomeFirstResponser 必须返回 YES,这意味着必须子类化。例如最常用的显示元素 UITableViewCell 和 UILabel 默认返回的是 NO
  2. UILongPressGestureRecognizer 直到 iOS 3.2 才提供, which means that the long press to initiate the menu display had to be implemented viatouchesBegan:withEvent:touchesMoved:withEvent:, andtouchesEnded:withEvent:. Every custom long press recognizer might use a different delay constant, which could easily confuse users who are used to another app's implementation.

而最新的 iOS 使用两种基本方法解决了这个问题,一个是表格单元格,另外一个是定制菜单选项。

指定情景: UITableViewCell on iOS 5

如果你只是想在 UITableViewCell 中使用系统提供的复制粘贴功能(大部分情况是这样),iOS 5.0 有更简单的方法:

01 - (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath {
02     return YES;
03 }
04  
05 - (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
06     if (action == @selector(copy:)) {
07         returnYES;    
08     }
09      
10     returnNO; 
11 }
12  
13 - (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
14     if (action == @selector(copy:)) {
15         [UIPasteboard generalPasteboard].string = [data objectAtIndex:indexPath.row];
16     }
17 }

该菜单调用 tableView:canPerformAction:forRowAtIndexPath:withSender 以确认是否该显示系统菜单选项并调用 tableView:performAction:forRowAtIndexPath:withSender: 当用户选择某个选项时.

定制菜单项

如果你想使用定制菜单项,下面代码比较隐晦,但非常灵活。你需要检测是否用户长按并显示菜单,而最简单的方法就是在表格单元格中使用 UILongPressGestureRecognizer

1 UILongPressGestureRecognizer *recognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
2 [cell addGestureRecognizer:recognizer];

为了让菜单显示,目标视图必须在 responder 链中,很多 UIKit 视图默认并无法成为一个 responder ,因此你需要之类这些视图重载 canBecomeFirstResponder 方法范围 YES

nid%3D1717%7Ctitle%3D%7Cdesc%3DA%20UIMenuController%20with%20custom%20menu%20items.%7Clink%3Dnone

在下面例子中,我们使用定制类 TSTableViewCell 并实现了长按选择器

01 - (void)longPress:(UILongPressGestureRecognizer *)recognizer { 
02     if (recognizer.state == UIGestureRecognizerStateBegan) {
03         TSTableViewCell *cell = (TSTableViewCell *)recognizer.view;
04         [cell becomeFirstResponder];
05          
06         UIMenuItem *flag = [[UIMenuItem alloc] initWithTitle:@"Flag"action:@selector(flag:)];
07         UIMenuItem *approve = [[UIMenuItem alloc] initWithTitle:@"Approve"action:@selector(approve:)];
08         UIMenuItem *deny = [[UIMenuItem alloc] initWithTitle:@"Deny"action:@selector(deny:)];
09  
10         UIMenuController *menu = [UIMenuController sharedMenuController];
11         [menu setMenuItems:[NSArray arrayWithObjects:flag, approve, deny, nil]];
12         [menu setTargetRect:cell.frame inView:cell.superview];
13         [menu setMenuVisible:YES animated:YES];
14     }
15 }
16  
17 - (void)flag:(id)sender {
18     NSLog(@"Cell was flagged");
19 }
20  
21 - (void)approve:(id)sender {
22     NSLog(@"Cell was approved");
23 }
24  
25 - (void)deny:(id)sender {
26     NSLog(@"Cell was denied");
27 }

There is only one small gotcha with UIMenuItem: if the specified action is not implemented by your view controller, that item will not appear in the menu.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值