下面是我的代码,我在点击菜单“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)
}