當(dāng)蘋果在 iOS 3.0 中增加了剪切、復(fù)制和粘貼功能時返十,它同時為開發(fā)者提供了 UIMenuController 組件用來定制該彈出菜單姨涡,但不幸的是,最開始的實現(xiàn)要很麻煩吧慢。
- 附加在菜單的視圖的
canBecomeFirstResponser
必須返回 YES涛漂,這意味著必須子類化。例如最常用的顯示元素UITableViewCell
和UILabel
默認(rèn)返回的是NO
-
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 中使用系統(tǒng)提供的復(fù)制粘貼功能(大部分情況是這樣)逢慌,iOS 5.0 有更簡單的方法:
- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
if (action == @selector(copy:)) {
returnYES;
}
returnNO;
}
- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
if (action == @selector(copy:)) {
[UIPasteboard generalPasteboard].string = [data objectAtIndex:indexPath.row];
}
}
該菜單調(diào)用 tableView:canPerformAction:forRowAtIndexPath:withSender
以確認(rèn)是否該顯示系統(tǒng)菜單選項并調(diào)用
tableView:performAction:forRowAtIndexPath:withSender:
當(dāng)用戶選擇某個選項時.
為了讓菜單顯示悠轩,目標(biāo)視圖必須在 responder 鏈中,很多 UIKit 視圖默認(rèn)并無法成為一個 responder
攻泼,因此你需要之類這些視圖重載 canBecomeFirstResponder
方法范圍 YES
在下面例子中火架,我們使用定制類 TSTableViewCell 并實現(xiàn)了長按選擇器
- (void)longPress:(UILongPressGestureRecognizer *)recognizer {
if (recognizer.state == UIGestureRecognizerStateBegan) {
TSTableViewCell *cell = (TSTableViewCell *)recognizer.view;
[cell becomeFirstResponder];
UIMenuItem *flag = [[UIMenuItem alloc] initWithTitle:@"Flag"action:@selector(flag:)];
UIMenuItem *approve = [[UIMenuItem alloc] initWithTitle:@"Approve"action:@selector(approve:)];
UIMenuItem *deny = [[UIMenuItem alloc] initWithTitle:@"Deny"action:@selector(deny:)];
UIMenuController *menu = [UIMenuController sharedMenuController];
[menu setMenuItems:[NSArray arrayWithObjects:flag, approve, deny, nil]];
[menu setTargetRect:cell.frame inView:cell.superview];
[menu setMenuVisible:YES animated:YES];
}
}
- (void)flag:(id)sender {
NSLog(@"Cell was flagged");
}
- (void)approve:(id)sender {
NSLog(@"Cell was approved");
}
- (void)deny:(id)sender {
NSLog(@"Cell was denied");
}
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.