2014-01-09 18 views
0

我正嘗試使用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自我,但我不知道如何才能獲得細胞,在其菜單觸發,所以我可以做進一步的行動關於細胞本身。

有人能幫我嗎?

謝謝。 Hai

回答

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

在MyCell.h的UITableViewCell的子類定義了小區所屬的小區的代表表視圖控制器。而回調函數當菜單條目MyCell.m

- (BOOL)canBecomeFirstResponder 
{ 
    return YES; 
} 

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

點擊

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

允許了myCell成爲第一個響應者和響應通過點擊菜單項中的handleMyAction行動。

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

這是回調函數,這將被稱爲當點擊菜單項的定義,它依次調用handMyAction功能細胞的委託(MyTableViewController,其中關於小區的邏輯可以實現。)

0

那麼你現在正在將UIGestureRecognizer添加到tableview本身。爲什麼不將它添加到每個單元格中(而是在它們設置時在cellForRowAtIndexPath中)?

+0

你的意思是在cellForRowAtIndexPath中,對嗎?即使我這樣做,菜單將觸發單元格,並且我的動作handleMyAction的處理程序將被調用,我們將在彈出菜單中選擇「我對這個單元格的操作」條目,但是,如何訪問handleMyAction函數中的單元格,因爲這個函數的唯一參數是發送者,所以它是UIMenuController。 – Hai

+0

實際上,如果您將手勢識別器設置爲單元格,發件人是手勢識別器本身,而gestureRecognizer.view是單元格。 – valheru

+0

起初我長按細胞和彈出菜單觸發,無論我設置手勢識別器在表視圖或表視圖的每個單元格上,發件人是識別器,我相信這是真的,如果識別器是正如你所建議的那樣,這個單元格是識別器。視圖將是單元格。但問題不在這裏。我確實需要訪問菜單條目的回調函數中的單元格,當我點擊彈出式菜單時。在這種情況下,回調函數的發送者始終是菜單本身。 – Hai

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]; 
} 

我希望這有助於!

相關問題