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の共有インスタンスの目的に反するのではないでしょうか。
私が理解している限り、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 {
}
///////////////////////////////////////////////////////
_
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()
}
}
ノート:
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
}
}