简单的方法来显示UITableViewCells上的“复制”popup窗口,如地址簿应用程序

是否有一个简单的方法UITableViewCell的子类显示“复制”UIMenuControllerpopup式的地址簿应用程序(见截图),在select一段时间后?

地址簿

iOS 5之前的方法是获取UIMenuController的共享实例,设置目标矩形和视图并调用-setMenuVisible:animated: 记住要在响应者中执行-canPerformAction:withSender:


iOS 5之后的方法(以前可作为未公开的function提供)是在您的数据源中实现这3种方法(请参阅https://developer.apple.com/reference/uikit/uitableviewdelegate#1653389 )。

 -(void)tableView:(UITableView*)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath*)indexPath withSender:(id)sender; -(BOOL)tableView:(UITableView*)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath*)indexPath withSender:(id)sender; -(BOOL)tableView:(UITableView*)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath*)indexPath; 

现在有用于在iOS 5中显示UITableView单元菜单的官方界面。示例(从表代表):

 - (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath { return YES; } - (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { return (action == @selector(copy:)); } - (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { if (action == @selector(copy:)){ UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; [[UIPasteboard generalPasteboard] setString:cell.textLabel.text]; } } 

我尝试修改UIMenuController的共享控制器来添加我自己的菜单项,我可以添加它并获取canPerformAction消息,但返回YES没有帮助; 我无法使我的自定义菜单项出现。 在我的实验中,它看起来像是仅支持复制,剪切和粘贴。 [ 编辑由于这是张贴,我已经学会了如何添加自定义菜单项。]

请注意,这只适用于所有三个委托方法都实施。

你的UITableViewCell子类可能看起来像这样

 @interface MenuTableViewCell : UITableViewCell { } - (IBAction)copy:(id)sender; - (void)showMenu; @end @implementation MenuTableViewCell - (BOOL)canBecomeFirstResponder { return YES; } - (BOOL)canPerformAction:(SEL)action withSender:(id)sender { if (action == @selector(copy:)) { return YES; } return NO; } - (IBAction)copy:(id)sender { } - (void)showMenu { [[UIMenuController sharedMenuController] setMenuVisible:NO animated:YES]; [self becomeFirstResponder]; [[UIMenuController sharedMenuController] update]; [[UIMenuController sharedMenuController] setTargetRect:CGRectZero inView:self]; [[UIMenuController sharedMenuController] setMenuVisible:YES animated:YES]; } @end 

和UITableView委托方法是一样的

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; MenuTableViewCell *cell = (MenuTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[MenuTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; } // Configure the cell. return cell; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { MenuTableViewCell *cell = (MenuTableViewCell *)[tableView cellForRowAtIndexPath:indexPath]; [cell showMenu]; } 

这里是复制detailTextLabel的Swift语法。

 override func tableView(_ tableView: UITableView, shouldShowMenuForRowAt indexPath: IndexPath) -> Bool { return (tableView.cellForRow(at: indexPath)?.detailTextLabel?.text) != nil } override func tableView(_ tableView: UITableView, canPerformAction action: Selector, forRowAt indexPath: IndexPath, withSender sender: Any?) -> Bool { return action == #selector(copy(_:)) } override func tableView(_ tableView: UITableView, performAction action: Selector, forRowAt indexPath: IndexPath, withSender sender: Any?) { if action == #selector(copy(_:)) { let cell = tableView.cellForRow(at: indexPath) let pasteboard = UIPasteboard.general pasteboard.string = cell?.detailTextLabel?.text } } 
  #pragma mark - COPY/PASTE Cell Text via Menu - (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath { return YES; } - (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { return (action == @selector(copy:)); } - (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { if (action == @selector(copy:)) { UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; UIPasteboard *pasteBoard = [UIPasteboard generalPasteboard]; [pasteBoard setString:cell.textLabel.text]; } }