簡體   English   中英

如何在UIMenuController中的自定義操作中獲取輕敲的表格視圖單元格

[英]How to get the tapped table view cell in custom action in 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;
}

當我按下一個單元格時,帶有自定義條目的上下文菜單會正確顯示。 但是,問題是我該如何實現處理自定義動作的方法,該方法應在輕擊的單元格上執行。

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

因為我只能從該方法中獲取信息,所以發送者即UIMenuController本身,但是我不知道如何獲取觸發了Menu的單元格,因此我可以對單元格本身進行進一步的操作。

有人可以幫我嗎?

謝謝。

好吧,您當前正在將UIGestureRecognizer添加到tableview本身。 為什么不將其添加到每個單元格中(在設置它們時在cellForRowAtIndexPath中)?

謝謝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);
}

稍后將在所按下的單元格中調用此函數。

第二步:創建UITableViewCell的子類MyCell

在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:)
}

這是回調函數的定義,當單擊菜單項時將調用該回調函數,並依次在單元格的委托(MyTableViewController,可以在其中實現有關單元格的邏輯)中調用handMyAction函數。

首先將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];
    }

現在,在菜單選擇器方法中,基於保存的indexPath選擇行。

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

    [mTableView setEditing:YES animated:YES];

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

我希望這有幫助!!!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM