web-dev-qa-db-ja.com

UITableViewCellのカスタムUIMenuItemを表示する方法

UITableViewCellを長押しするとポップアップするUIMenuControllerがカスタムUIMenuItemsを表示するようにします。

カスタムアイテムをviewDidLoadに設定しました

UIMenuItem *testMenuItem = [[UIMenuItem alloc] initWithTitle:@"Test" action:@selector(test:)];
[[UIMenuController sharedMenuController] setMenuItems: @[testMenuItem]];

次に、適切なデリゲートメソッドをすべて設定します。

- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath {
    return YES;
}

-(BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
    return (action == @selector(copy:) || action == @selector(test:));
}

- (BOOL)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
    if (action == @selector(copy:)) {
         // do stuff
    }

    return YES;
}

しかし、私が許可しているのは「コピー」アイテムとカスタムアイテムだけなので、それがすべてです。ただし、カスタムアイテムは表示されません。

ジェスチャレコグナイザをセル自体に追加することもできますが、UIMenuControllerの共有インスタンスの目的に反するのではないでしょうか。

22
leberwurstsaft

私が理解している限り、2つの主要な問題があります。

1)_tableView canPerformAction:_がカスタムセレクターをサポートすることを期待していますが、ドキュメントではUIResponderStandardEditActionsの2つのみをサポートしていると記載されています(コピーまたは貼り付け)。

2)menuItemsプロパティを初期化してカスタムメニューオプションを追加するため、|| action == @selector(test:)の部分は必要ありません。この項目セレクターの場合、チェックは自動的に行われます。

カスタムメニュー項目を表示して機能させるためにできることは次のとおりです。

1)テーブルビューのデリゲートメソッドを修正します。

a)

_UIMenuItem *testMenuItem = [[UIMenuItem alloc] initWithTitle:@"Test" action:@selector(test:)];
[[UIMenuController sharedMenuController] setMenuItems: @[testMenuItem]];
[[UIMenuController sharedMenuController] update];
_

b)

_- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath {
    return YES;
}

-(BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
    return (action == @selector(copy:));
}

- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
    // required
}
_

2)セルをセットアップします(サブクラス化UITableViewCell)。

_-(BOOL) canPerformAction:(SEL)action withSender:(id)sender {
    return (action == @selector(copy:) || action == @selector(test:));
}

-(BOOL)canBecomeFirstResponder {
    return YES;
}

/// this methods will be called for the cell menu items
-(void) test: (id) sender {

}

-(void) copy:(id)sender {

}
///////////////////////////////////////////////////////
_
51
A-Live

UITableViewCellのコピーとカスタムアクションを実装するには:

アプリケーションで一度、カスタムアクションを登録します。

struct Token { static var token: dispatch_once_t = 0 }
dispatch_once(&Token.token) {
    let customMenuItem = UIMenuItem(title: "Custom", action: #selector(MyCell.customMenuItemTapped(_:))
    UIMenuController.sharedMenuController().menuItems = [customMenuItem]
    UIMenuController.sharedMenuController().update()
}

UITableViewCellサブクラスで、カスタムメソッドを実装します。

func customMenuItemTapped(sender: UIMenuController) {
    // implement custom action here
}

UITableViewDelegateで、次のメソッドを実装します。

override func tableView(tableView: UITableView, shouldShowMenuForRowAtIndexPath indexPath: NSIndexPath) -> Bool {
    return true
}

override func tableView(tableView: UITableView, canPerformAction action: Selector, forRowAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject?) -> Bool {
    return action == #selector(NSObject.copy(_:)) || action == #selector(MyCell.customMenuItemTapped(_:))
}

override func tableView(tableView: UITableView, performAction action: Selector, forRowAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject?) {
    switch action {
    case #selector(NSObject.copy(_:)):
        // implement copy here
    default:
        assertionFailure()
    }
}

ノート:

8
Senseful

Swift 3:

AppDelegateでdidFinishLaunchingWithOptions:

let customMenuItem = UIMenuItem(title: "Delete", action:
#selector(TableViewCell.deleteMessageActionTapped(sender:)))
        UIMenuController.shared.menuItems = [customMenuItem]
        UIMenuController.shared.update()

tableViewContollerクラスで:

override func tableView(_ tableView: UITableView, shouldShowMenuForRowAt indexPath: IndexPath) -> Bool {
    return true
}

override func tableView(_ tableView: UITableView, canPerformAction action: Selector, forRowAt indexPath: IndexPath, withSender sender: Any?) -> Bool {
        return action == #selector(copy(_:)) || action == #selector(TableViewCell.yourActionTapped(sender:))
    }



 override func tableView(_ tableView: UITableView, performAction action: Selector, forRowAt indexPath: IndexPath, withSender sender: Any?) {
   if action == #selector(copy(_:)) {
        let pasteboard = UIPasteboard.general
        pasteboard.string = messages[indexPath.row].text
   }
}
1
Maksim Kniazev