我正在尝试使用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自己,但我不知道如何获取菜单触发的单元格,所以我可以对单元格本身做进一步的操作。
有人可以帮我吗?
感谢。 海
答案 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];
}
我希望这会有所帮助!!!