所以,我不确定我在这里做错了什么,但是我有一个UIViewController,它上面有一个UICollectionView。在UIViewController的viewDidLoad
方法中,我执行以下操作,它不会向显示的弹出窗口添加任何自定义菜单项。
UIMenuItem *removeItem = [[UIMenuItem alloc] initWithTitle:@"Remove" action:@selector(handleRemoveItem:)];
UIMenuItem *duplicateItem = [[UIMenuItem alloc] initWithTitle:@"Duplicate" action:@selector(handleDuplicateItem:)];
[[UIMenuController sharedMenuController] setMenuItems:@[removeItem, duplicateItem]];
[removeItem release];
[duplicateItem release];
我确实在所有情况下都设置了collectionView:shouldShowMenuForItemAtIndexPath:
和collectionView:canPerformAction:forItemAtIndexPath:withSender:
以返回YES
,但无论如何,只会显示剪切,复制和粘贴。
我没有完全实现这一点,还是我没有做到这一点?
P.S。 - 我确实在整个谷歌中查看了尽可能多的示例,但我找不到任何有用的内容。
答案 0 :(得分:6)
我可以按照此链接(https://stackoverflow.com/a/13618212/2313416)上的说明进行即兴创作,从而在UICollectionViewCell上实现自定义菜单。
在我的UICollectionViewController中,我通过将链接添加到菜单控制器来实现自定义菜单项。
然后我在UICollectionViewController中实现了以下内容:
- (BOOL)collectionView:(UICollectionView *)cv canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
return NO;
}
- (BOOL)collectionView:(UICollectionView *)cv shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (void)collectionView:(UICollectionView *)cv performAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
NSLog(@"perform action:%@", NSStringFromSelector(action));
}
在我的UICollectionViewCell中,我实现了类似的以下内容:
- (BOOL)canBecomeFirstResponder {
return YES;
}
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
if (action == @selector(onCustom1:)) {
return YES;
}
if (action == @selector(onCustom2:)) {
return YES;
}
return NO;
}
这些操作必须与Collection Controller中实现的操作相同。
如果想要包含复制或粘贴功能,请将它们添加到canPerformAction:然后更改collectionView :: canPerformAction:返回YES。
这可能不是最好的方式,但对我有用。
答案 1 :(得分:3)
你是对的。在桌面视图单元格或集合视图单元格上长按时,无法自定义显示的菜单。
我在书中讨论了这个问题:
http://www.apeth.com/iOSBook/ch21.html#_table_view_menus
正如我所说,复制,剪切和粘贴是您可以拥有的唯一选择。如果要自定义菜单,则必须从其他菜单中发出菜单。
编辑:在本书的iOS 7版本中,我演示了一种方法。对于表格视图单元格和集合视图单元格来说,它是相同的,因此我将从表格视图单元格解决方案开始。诀窍是您必须在单元子类中实现操作方法。例如,如果您的自定义操作选择器为abbrev:
,则必须对单元格进行子类化并实现abbrev:
:
这是唯一棘手的部分。然后,回到您的控制器类中,您将abbrev:
完全按照您对任何菜单所做的操作。在shouldShowMenuForRowAtIndexPath:
中,将其添加到自定义菜单中。然后按照您的预期实现canPerformAction:
和performAction:
(一直滚动到底部):
这里是集合视图单元的并行实现:单元子类:
控制器(一直滚动到底部):
在我的书的iOS 8版本中,这些方法也被翻译成Swift(并非没有一些困难)。
答案 2 :(得分:1)
第1步:创建菜单项
UIMenuItem* miCustom1 = [[UIMenuItem alloc] initWithTitle:@"Custom 1" action:@selector(onCustom1:)];
UIMenuItem* miCustom2 = [[UIMenuItem alloc] initWithTitle: @"Custom 2" action:@selector(onCustom2:)];
第2步:创建MenuController
UIMenuController* mc = [UIMenuController sharedMenuController];
步骤3:向菜单控制器添加项目
mc.menuItems = [NSArray arrayWithObjects: miCustom1, miCustom2, nil];
第4步:为项目创建行动方法
- (void) onCustom1: (UIMenuController*) sender
{
}
- (void) onCustom2: (UIMenuController*) sender
{
}
步骤5:可选择为动作设置FirstResponder
- (BOOL) canPerformAction:(SEL)action withSender:(id)sender
{
if ( action == @selector( onCustom1: ) )
{
return YES; // logic here for context menu show/hide
}
if ( action == @selector( onCustom2: ) )
{
return NO; // logic here for context menu show/hide
}
if ( action == @selector( copy: ) )
{
// turn off copy: if you like:
return NO;
}
return [super canPerformAction: action withSender: sender];
}
步骤6:最后在某些按钮操作上显示您的MenuController
UIMenuController* mc = [UIMenuController sharedMenuController];
CGRect bounds = sender.view.bounds;
[mc setTargetRect: sender.view.frame inView:sender.view.superview];
[mc setMenuVisible:YES animated: YES];