UIMenuController使用

本文介绍如何在iOS5中使用UIMenuController来轻松实现UITableViewCell的复制粘贴功能,并提供自定义上下文菜单的方法。

转自:http://blog.youkuaiyun.com/piziliweiguang/article/details/8281007

当苹果在 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.


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值