如何在UIMenuController中的自定义操作中获取抽头表视图单元格

时间:2014-01-09 23:19:40

标签: ios ios7 uitableview uimenucontroller

我正在尝试使用UIMenuController对表格单元格执行自定义操作,长时间按下UIMenuController会触发该操作。

我在UITableViewController的子类的viewDidLoad方法中注册了UILongPressGestureRecognizer,并使用@selector(handleMyAction)添加了自定义项。

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self.refreshControl addTarget:self action:@selector(refreshView:) forControlEvents:UIControlEventValueChanged];

    UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
    longPressGesture.minimumPressDuration = .5;
    longPressGesture.delegate = self;
    [self.tableView addGestureRecognizer:longPressGesture];
}

-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
{
    if(gestureRecognizer.state == UIGestureRecognizerStateBegan)
    {
        CGPoint point = [gestureRecognizer locationInView:self.tableView];
        NSIndexPath * indexPath = [self.tableView indexPathForRowAtPoint:point];
        if(indexPath == nil) return ;
        UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];

        UIMenuItem *it = [[UIMenuItem alloc] initWithTitle:@"My Action on this cell" action:@selector(handleMyAction:)];
        UIMenuController *menu = [UIMenuController sharedMenuController];
        [menu setMenuItems:[NSArray arrayWithObjects:it, nil]];
        [menu setTargetRect:cell.frame inView:cell.superview];
        [menu setMenuVisible:YES animated:YES];
        [self becomeFirstResponder];
    }
}

我也覆盖了

- (BOOL)canBecomeFirstResponder{
    return YES;
}

当我按下一个单元格时,带有自定义条目的上下文菜单会正确显示。但是,问题是我如何实现处理自定义操作的方法,应该在tapped单元格上执行。

- (void)handleMyAction:(id)sender
{
    NSLog(@"Action triggered, however need some way to refer the tapped cell");
}

因为我在这个方法中可以获得的唯一信息是发送者,这是UIMenuController自己,但我不知道如何获取菜单触发的单元格,所以我可以对单元格本身做进一步的操作。

有人可以帮我吗?

感谢。 海

3 个答案:

答案 0 :(得分:0)

那么你现在正在向tableview本身添加UIGestureRecognizer。为什么不将它添加到每个单元格(在设置时在cellForRowAtIndexPath中)?

答案 1 :(得分:0)

谢谢valheru。我找到了一个“很好”的方法来实现这个目标:)

第一步:在MyTableViewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];

    UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
    longPressGesture.minimumPressDuration = .5;
    longPressGesture.delegate = self;
    [self.view addGestureRecognizer:longPressGesture];
}

在表视图控制器上注册长按的手势识别器。

- (BOOL)canBecomeFirstResponder
{
    return YES;
}

允许MyTableViewController响应长按并弹出上下文菜单。

-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
{
    if(gestureRecognizer.state == UIGestureRecognizerStateBegan)
    {
        CGPoint point = [gestureRecognizer locationInView:self.tableView];
        NSIndexPath * indexPath = [self.tableView indexPathForRowAtPoint:point];
        if(indexPath == nil) return ;

        MyCell *cell = (MyCell *)[self.tableView cellForRowAtIndexPath:indexPath];
        UIMenuItem *determine = [[UIMenuItem alloc] initWithTitle:@"My Action on this cell" action:@selector(handleMyAction:)];
        UIMenuController *menu = [UIMenuController sharedMenuController];
        [menu setMenuItems:[NSArray arrayWithObjects:determine, nil]];
        [menu setTargetRect:cell.frame inView:cell.superview];
        [menu setMenuVisible:YES animated:YES];
        [cell becomeFirstResponder]; //here set the cell as the responder of the menu action
        cell.delegate = self;// this is optional, if you don't want to implement logic in cell class
    }
}

当我长按单元格时,创建UIMenuController并弹出窗口。

-(void)handleMyAction: (UITableViewCell *)cell
{
    NSLog(@"%@", cell);
}

稍后将从被按下的单元格中调用此函数。

第二步:创建一个名为MyCell的UITableViewCell的子类

在MyCell.h中定义了单元格所属的表视图控制器作为单元格的委托。单击菜单项时的回调函数

@property (nonatomic, strong) MyTableViewController *delegate;
-(void)handleMyAction:(id)sender;

在MyCell.m中

- (BOOL)canBecomeFirstResponder
{
    return YES;
}

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
    if(action == @selector(handleMyAction:))
    {
        return YES;
    }
    return NO;
}

允许MyCell成为第一个响应者并通过单击菜单项来响应handleMyAction操作。

-(void)handleMyAction:(id)sender
{
    [self.delegate handleMyAction:self]; //it's a coincidence both functions have the same name:)
}

这是回调函数的定义,当单击菜单项时将调用该函数,然后它又调用单元格委托中的handMyAction函数(MyTableViewController,可以实现有关单元格的逻辑)。 )

答案 2 :(得分:0)

首先将NSIndexPath类型声明为类变量。

@property (nonatomic, strong) NSIndexPath *savedIndexPathForThePressedCell;

现在在长按手势识别器功能中,使用识别器视图获取TableViewCell。现在保存TableViewCell的IndexPath

     - (void)longPressGestureFunction:(UILongPressGestureRecognizer *)recognizer
    {
        UITableViewCell *lTableViewCell = (UITableViewCell *)recognizer.view;
        [lTableViewCell becomeFirstResponder];

        /*Save the Indexpath of the cell pressed*/
        self.savedIndexPathForThePressedCell = [mTableView indexPathForCell:lTableViewCell];

if (recognizer.state == UIGestureRecognizerStateBegan)
    {
        UIMenuItem *MenuDelete = [[UIMenuItem alloc] initWithTitle:@"Delete" action:@selector(Delete:)];
        UIMenuItem *MenuForward = [[UIMenuItem alloc] initWithTitle:@"Forward" action:@selector(Forward:)];
        UIMenuItem *MenuAddToContacts = [[UIMenuItem alloc] initWithTitle:@"Add To Contacts" action:@selector(addToContacts:)];

        mSharedMenu = [UIMenuController sharedMenuController];
[mSharedMenu setMenuItems:[NSArray arrayWithObjects: MenuDelete, MenuForward, nil]];

        [mSharedMenu setMenuVisible:YES animated:YES];
    }

现在在Menu选择器方法中,根据保存的indexPath选择行。

- (void)Delete:(id)sender {
//  NSLog(@"\n Delete Selected \n");

    [mTableView setEditing:YES animated:YES];

    [mTableView selectRowAtIndexPath:self.savedIndexPathForThePressedCell animated:YES scrollPosition:UITableViewScrollPositionNone];
}

我希望这会有所帮助!!!