UIMenuController与自定义项目不使用UICollectionview

Hee*_*ena 6 objective-c uimenucontroller uiresponder uicollectionview

我在长按UICollectionViewCell时添加了自定义菜单控制器

    [self becomeFirstResponder];
    UIMenuItem *menuItem = [[UIMenuItem alloc] initWithTitle:@"Custom Action"
                                                      action:@selector(customAction:)];
    [[UIMenuController sharedMenuController] setMenuItems:[NSArray arrayWithObject:menuItem]];
    [[UIMenuController sharedMenuController] setTargetRect: self.frame inView:self.superview];
    [[UIMenuController sharedMenuController] setMenuVisible:YES animated: YES];
Run Code Online (Sandbox Code Playgroud)

canBecomeFirstResponder也被调用

- (BOOL)canBecomeFirstResponder {
    // NOTE: This menu item will not show if this is not YES!
    return YES;
}
Run Code Online (Sandbox Code Playgroud)

//未调用此方法

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    NSLog(@"canPerformAction");
    // The selector(s) should match your UIMenuItem selector
    if (action == @selector(customAction:)) {
        return YES;
    }
    return NO;
}
Run Code Online (Sandbox Code Playgroud)

我也实现了这些方法

- (BOOL)collectionView:(UICollectionView *)collectionView
      canPerformAction:(SEL)action
    forItemAtIndexPath:(NSIndexPath *)indexPath
            withSender:(id)sender {


    if([NSStringFromSelector(action) isEqualToString:@"customAction:"]){
        NSLog(@"indexpath : %@",indexPath);
        UIAlertView *alertview = [[UIAlertView alloc] initWithTitle:@"warning.." message:@"Do you really want to delete this photo?" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
        [alertview show];
        return YES;
    }

    return YES;

}

- (BOOL)collectionView:(UICollectionView *)collectionView shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath {
    return YES;
}

- (void)collectionView:(UICollectionView *)collectionView
         performAction:(SEL)action
    forItemAtIndexPath:(NSIndexPath *)indexPath
            withSender:(id)sender {
    NSLog(@"performAction");
}
Run Code Online (Sandbox Code Playgroud)

虽然它只显示"剪切,复制和粘贴"菜单

Nil*_*z11 7

也许有点晚了但我可能会找到一个更好的解决方案,仍然搜索这个:

在你的UICollectionViewController的viewDidLoad中添加你的项目:

UIMenuItem *menuItem = [[UIMenuItem alloc] initWithTitle:@"Title" action:@selector(action:)];
[[UIMenuController sharedMenuController] setMenuItems:[NSArray arrayWithObject:menuItem]];
Run Code Online (Sandbox Code Playgroud)

添加以下委托方法:

//This method is called instead of canPerformAction for each action (copy, cut and paste too)
- (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
        if (action == @selector(action:)) {
            return YES;
        }
        return NO;
    }
    //Yes for showing menu in general
    - (BOOL)collectionView:(UICollectionView *)collectionView shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath {
        return YES;
    }
Run Code Online (Sandbox Code Playgroud)

如果你还没有UICollectionViewCell的子类.添加为项目指定的方法:

- (void)action:(UIMenuController*)menuController {

}
Run Code Online (Sandbox Code Playgroud)

这样您就不需要任何becomeFirstResponder或其他方法.如果您将单元格本身作为参数调用一般方法,则可以在一个位置执行所有操作,并且可以轻松处理不同的单元格.

编辑:不知何故,uicollectionview需要存在此方法(此方法不会调用您的自定义操作,我认为uicollectionview只检查存在)

- (void)collectionView:(UICollectionView *)collectionView performAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {

}
Run Code Online (Sandbox Code Playgroud)


aya*_*cin 5

您需要从自定义UICollectionViewCell触发委托函数

这是我的Swift3的工作示例代码

CollectionViewController

override func viewDidLoad() {
    super.viewDidLoad()
    let editMenuItem = UIMenuItem(title: "Edit", action: NSSelectorFromString("editCollection"))
    let deleteMenuItem = UIMenuItem(title: "Delete", action: NSSelectorFromString("deleteCollection"))
    UIMenuController.shared.menuItems = [editMenuItem, deleteMenuItem]

}

override func collectionView(_ collectionView: UICollectionView, shouldShowMenuForItemAt indexPath: IndexPath) -> Bool {
    return true
}

override func collectionView(_ collectionView: UICollectionView, canPerformAction action: Selector, forItemAt indexPath: IndexPath, withSender sender: Any?) -> Bool {
    return action == NSSelectorFromString("editCollection") || action == NSSelectorFromString("deleteCollection")
}

override func collectionView(_ collectionView: UICollectionView, performAction action: Selector, forItemAt indexPath: IndexPath, withSender sender: Any?) {
    print("action:\(action.description)")
    //Custom actions here..
}
Run Code Online (Sandbox Code Playgroud)

将以下函数添加到自定义UICollectionViewCell

override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
    return action == NSSelectorFromString("editCollection") || action == NSSelectorFromString("deleteCollection")
}
Run Code Online (Sandbox Code Playgroud)

从单元格调用委托函数(需要在您的自定义UICollectionViewCell中)

func editCollection()
{
    let collectionView = self.superview as! UICollectionView
    let d:UICollectionViewDelegate = collectionView.delegate!
    d.collectionView!(collectionView, performAction: NSSelectorFromString("editCollection"), forItemAt: collectionView.indexPath(for: self)!, withSender: self)
}
func deleteCollection()
{
    let collectionView = self.superview as! UICollectionView
    let d:UICollectionViewDelegate = collectionView.delegate!
    d.collectionView!(collectionView, performAction: NSSelectorFromString("deleteCollection"), forItemAt: collectionView.indexPath(for: self)!, withSender: self)
}
Run Code Online (Sandbox Code Playgroud)


Reg*_*ion 4

我刚刚花了两天时间试图找出“正确”的方法来做到这一点,并用周围的一些建议指出了错误的做法。

本文展示了执行此操作的正确方法。我希望通过将其发布在这里,可以为某人节省几个小时。

http://dev.glide.me/2013/05/custom-item-in-uimenucontroller-of.html