5

所以,我不确定我是否在这里做错了,但我有一个 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,但无论如何,只会显示剪切、复制和粘贴。

我没有完全实现这一点,还是我做得不对?

PS-我确实在整个谷歌中查看了尽可能多的示例,但没有找到任何帮助。

4

3 回答 3

7

通过遵循此链接 ( 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。

这可能不是最好的方法,但对我有用。

于 2013-04-24T00:24:54.343 回答
4

你是对的。当您长按表格视图单元格或集合视图单元格时,无法自定义出现的菜单。

我在书中讨论了这个问题:

http://www.aeth.com/iOSBook/ch21.html#_table_view_menus

正如我在那里所说,复制、剪切和粘贴是您唯一的选择。如果要自定义菜单,则必须使菜单源自其他内容。

编辑:在我的书的 iOS 7 版本中,我演示了一种方法来做到这一点。表格视图单元格和集合视图单元格也是如此,所以我将从表格视图单元格解决方案开始。诀窍是您必须在单元子类中实现 action 方法。例如,如果您的自定义操作选择器是abbrev:,则必须子类化单元格并实现abbrev:

https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/iOS7bookExamples/bk2ch08p454tableCellMenus2/ch21p718sections/MyCell.m

这是唯一棘手的部分。然后,回到您的控制器类中,您所做的abbrev:正是您对任何菜单所做的。在shouldShowMenuForRowAtIndexPath:中,将其添加到自定义菜单。然后像你期望的那样实现(一直滚动到底部)canPerformAction:performAction:

https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/iOS7bookExamples/bk2ch08p454tableCellMenus2/ch21p718sections/RootViewController.m

这是集合视图单元格的并行实现:单元格子类:

https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/iOS7bookExamples/bk2ch08p466collectionViewFlowLayout2/ch21p748collectionViewFlowLayout2/Cell.m

和控制器(一直滚动到底部):

https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/iOS7bookExamples/bk2ch08p466collectionViewFlowLayout2/ch21p748collectionViewFlowLayout2/ViewController.m

在我的 iOS 8 版本中,这些方法也被翻译成 Swift(并非没有一些困难)。

于 2013-04-03T04:26:15.627 回答
1

第 1 步:创建菜单项

UIMenuItem* miCustom1 = [[UIMenuItem alloc] initWithTitle:@"Custom 1" action:@selector(onCustom1:)];
UIMenuItem* miCustom2 = [[UIMenuItem alloc] initWithTitle: @"Custom 2" action:@selector(onCustom2:)];

第 2 步:创建菜单控制器

UIMenuController* mc = [UIMenuController sharedMenuController];

第 3 步:将项目添加到菜单控制器

mc.menuItems = [NSArray arrayWithObjects: miCustom1, miCustom2, nil];

第 4 步:为项目创建操作方法

- (void) onCustom1: (UIMenuController*) sender
{
}

- (void) onCustom2: (UIMenuController*) sender
{
}

第 5 步:可以选择为 Actions 设置 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];
于 2013-04-03T04:06:05.900 回答