下面是我的代码,我在点击菜单“pasteAndGo”时发现,有两个日志字符串被打印出来:1。粘贴并继续显示2。单击“粘贴并继续”。我的要求是当显示菜单时,显示日志“粘贴并开始显示”。单击后,将显示日志“粘贴并单击”。

class MyTextField: UITextField {

      private func Init() {
          let menuController: UIMenuController = UIMenuController.shared
          menuController.isMenuVisible = true
          let pasteAndGoMenuItem: UIMenuItem = UIMenuItem(title: "pasteAndGo", action: #selector(pasteAndGo(sender:)))

          let myMenuItems: NSArray = [pasteAndGoMenuItem]
          menuController.menuItems = myMenuItems as? [UIMenuItem]
      }

      @objc private func pasteAndGo(sender: UIMenuItem) {
          Print("paste and go clicked")
      }

      override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
          let pasteboard = UIPasteboard.general

          if action == #selector(pasteAndGo) {
              if pasteboard.url != nil {
              Print("paste and go show")
                  return true
          } else {
              return false
          }
        }

        return super.canPerformAction(action, withSender: sender)
    }
}

最佳答案

您的代码按实现方式工作:
在按pasteAndGo菜单项的瞬间,UIKit框架调用canPerformAction来询问是否允许它执行操作。在这里,您可以打印“粘贴并显示”
由于您返回true,您的操作pasteAndGo(sender:)将被执行并打印“粘贴并单击”
要对显示的菜单项做出反应,您必须使用UIMenuControllerWillShowMenu通知注册到通知中心,如下所示:

// create a property
var token:NSObjectProtocol?

// then add observer
self.token = NotificationCenter.default.addObserver(forName: Notification.Name.UIMenuControllerWillShowMenu,
                                           object: nil,
                                           queue: OperationQueue.main)
    { _ in
        print ("paste and go show")
    }

一旦你的viewcontroller被解雇,别忘了取消订阅(NotificationCenter.default.removeObserver)。
if let t = self.token {
    NSNotificationCenter.defaultCenter().removeObserver(t)
}

更新
您也可以在Init中执行此操作(不带属性)
// in Init
var token = NotificationCenter.default.addObserver(forName: Notification.Name.UIMenuControllerWillShowMenu,
                                           object: nil,
                                           queue: OperationQueue.main)
    { _ in
        print ("paste and go show")
        NSNotificationCenter.defaultCenter().removeObserver(token)
    }

10-08 06:08