6

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];

canBecomeFirstResponder も呼び出されています

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

//このメソッドは呼び出されていません

- (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;
}

これらのメソッドも実装しました

- (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");
}

「切り取り、コピー、貼り付け」メニューしか表示されていませんが

4

6 に答える 6

8

少し遅いかもしれませんが、まだこれを探している人のためのより良い解決策を見つけたかもしれません:

UICollectionViewController の viewDidLoad に項目を追加します。

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

次のデリゲート メソッドを追加します。

//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;
    }

まだサブクラス化していない場合は、UICollectionViewCell をサブクラス化します。アイテムに指定した方法を追加します。

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

}

この方法では、becomeFirstResponder やその他のメソッドは必要ありません。すべてのアクションが 1 か所にあり、セル自体をパラメーターとして一般的なメソッドを呼び出すと、さまざまなセルを簡単に処理できます。

編集:どういうわけか、uicollectionview にはこのメソッドの存在が必要です (このメソッドはカスタム アクションに対して呼び出されません。uicollectionview は存在をチェックするだけだと思います)

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

}
于 2013-09-10T17:28:35.067 に答える
6

カスタム 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..
}

カスタム UICollectionViewCell に次の関数を追加します

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

セルからデリゲート関数を呼び出すには (カスタム 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)
}
于 2016-10-10T10:59:23.910 に答える
0

Swiftを使用してカスタム項目のみを表示する (デフォルトのカット、ペーストなどを使用しない) iOS 9では、次のコードを使用することしかできませんでした。

オンメソッドviewDidLoad:

let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(contextMenuHandler))
longPressRecognizer.minimumPressDuration = 0.3
longPressRecognizer.delaysTouchesBegan = true
self.collectionView?.addGestureRecognizer(longPressRecognizer)

メソッドのオーバーライドcanBecomeFirstResponder:

override func canBecomeFirstResponder() -> Bool {
    return true
}

これら 2 つのコレクション関連のメソッドをオーバーライドします。

override func collectionView(collectionView: UICollectionView, shouldShowMenuForItemAtIndexPath indexPath: NSIndexPath) -> Bool {
    return true
}

override func collectionView(collectionView: UICollectionView, canPerformAction action: Selector,
                             forItemAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject?) -> Bool {
    return (action == #selector(send) || action == #selector(delete))
}

ジェスチャ ハンドラ メソッドを作成します。

func contextMenuHandler(gesture: UILongPressGestureRecognizer) {

    if gesture.state == UIGestureRecognizerState.Began {

        let indexPath = self.collectionView?.indexPathForItemAtPoint(gesture.locationInView(self.collectionView))

        if indexPath != nil {

            self.selectedIndexPath = indexPath!

            let cell = self.collectionView?.cellForItemAtIndexPath(self.selectedIndexPath)
            let menu = UIMenuController.sharedMenuController()
            let sendMenuItem = UIMenuItem(title: "Send", action: #selector(send))
            let deleteMenuItem = UIMenuItem(title: "Delete", action: #selector(delete))
            menu.setTargetRect(CGRectMake(0, 5, 60, 80), inView: (cell?.contentView)!)
            menu.menuItems = [sendMenuItem, deleteMenuItem]
            menu.setMenuVisible(true, animated: true)
        }
    }
}

最後に、セレクターのメソッドを作成します。

func send() {
    print("Send performed!")
}

func delete() {
    print("Delete performed!")
}

それが役立つことを願っています。:)

乾杯。

于 2016-07-06T14:06:31.297 に答える