我已经在显示UIMenuController
. 但是当菜单显示时,相应的表格视图单元格会取消选择。在显示菜单之前,我会根据需要调用[self becomeFirstResponder]
. 我认为这个调用取消选择单元格,但是如何使它在UIMenuController
可见时保持选中状态?
4 回答
根据文档,当您不想取消选择行时,在您的UITableViewDelegate
, 中覆盖tableView:willDeselectRowAtIndexPath:
并返回。nil
一种更简单的实现方法是使用特定的 UITableViewDelegate 方法来处理 UIMenuController。但首先,要使单元格保持选中状态,请将呈现菜单的单元格的值存储在您的类中:
NSIndexPath *_editingIndexPath;
然后实现 UITableViewDelegateMethods:
- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCustomTableViewCell *cell = (MyCustomTableViewCell *) [_tableView cellForRowAtIndexPath:indexPath];
_editingIndexPath = indexPath;
cell.showingMenu = YES;
return YES;
}
- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender
{
if (action == @selector(copy:)) {
return YES;
}
return NO;
}
- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender
{
if (action == @selector(copy:))
{
UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
if (cell && [cell isKindOfClass:[MessageConversationCell class]])
{
[UIPasteboard generalPasteboard].string = cell.textLabel.text;
}
}
}
上面的代码将负责在长按后在单元格上显示“复制”菜单。现在,如果您希望在显示菜单时单元格保持选中状态:
在名为“showingMenu”的自定义单元格中添加一个@property(请注意,此属性已在此答案的第一个代码块中设置)。
@property (nonatomic, assign) BOOL showingMenu;
将以下方法添加(或修改,如果已经存在)到您的自定义单元格。这将负责在菜单尝试取消突出显示后保持单元格突出显示(您可以实现自己的逻辑来突出显示单元格,在这种情况下将其放在 if 条件的第一个分支中):
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
{
if (_showingMenu)
{
[super setHighlighted:YES]
}
else
{
[super setHighlighted:highlighted];
}
}
添加一个观察者,以便在将要显示菜单时得到通知。这进入视图控制器,而不是自定义单元格:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didShowEditMenu:) name:UIMenuControllerDidShowMenuNotification object:nil];
在视图控制器上添加显示菜单时要调用的方法:
- (void)didShowEditMenu:(NSNotification *)not {
[_tableView selectRowAtIndexPath:_editingIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
MyCustomTableViewCell *cell = (MyCustomTableViewCell*)[_conversationTableView cellForRowAtIndexPath:_editingIndexPath];
cell.showingMenu = NO;
}
并且不要忘记在不再需要时移除观察者:
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIMenuControllerDidShowMenuNotification object:nil];
这将在长按一个单元格时显示一个菜单,并保持该单元格被选中直到菜单消失,因为选择了一个选项或因为用户点击了其他地方。当您选择消息时,它的工作方式与 Whatsapp 的工作方式非常相似。
您说您正在打电话[self becomeFirstResponder]
,但您的问题并未表明 self 是哪个对象。我猜self
是你的控制器。您应该将becomeFirstResponder
消息发送到生成 UIMenuController 的 UITableViewCell。
- (void)longPress:(UILongPressGestureRecognizer *)recognizer
{
if (recognizer.state == UIGestureRecognizerStateBegan)
{
TSTableViewCell *cell = (TSTableViewCell *)recognizer.view;
//This is your problem
[cell becomeFirstResponder];
UIMenuItem *flag = [[UIMenuItem alloc] initWithTitle:@"Flag" action:@selector(flag:)];
UIMenuItem *approve = [[UIMenuItem alloc] initWithTitle:@"Approve" action:@selector(approve:)];
UIMenuItem *deny = [[UIMenuItem alloc] initWithTitle:@"Deny" action:@selector(deny:)];
UIMenuController *menu = [UIMenuController sharedMenuController];
[menu setMenuItems:[NSArray arrayWithObjects:flag, approve, deny, nil]];
[menu setTargetRect:cell.frame inView:cell.superview];
[menu setMenuVisible:YES animated:YES];
}
}
我找到了这个解决方案:
- (void)handleLongPress:(UILongPressGestureRecognizer *)longPressRecognizer
{
if (longPressRecognizer.state == UIGestureRecognizerStateBegan) {
UITableViewCell *cell = (UITableViewCell *)longPressRecognizer.view;
[cell setSelected:YES];
...
}
}