如何让FinderSync自定义NSMenuItem显示在新建文件夹项正下方
实现方案
你当前调用menu.addItem(menuItem)添加自定义菜单项时,系统会默认将返回的自定义项追加到Finder对应菜单的末尾,因此会出现在菜单最底部。要将自定义菜单调整到「New Folder(新建文件夹)」正下方,可通过菜单显示前的位置调整逻辑实现,步骤如下:
- 给自定义根菜单项设置唯一tag作为身份标识,避免和系统菜单项混淆
- 监听系统菜单即将弹出的通知,在菜单渲染前完成位置调整
- 匹配到「New Folder」菜单项的位置后,将自定义菜单移动到它的下一个索引位即可
完整实现代码
首先定义自定义菜单的唯一tag常量,建议选不易和系统tag冲突的数值:
private let kCustomRootMenuItemTag: Int = 78945
调整原有menu(for menuKind: FIMenuKind)方法实现:
override func menu(for menuKind: FIMenuKind) -> NSMenu { let menu = NSMenu(title: "") let rootCustomItem = NSMenuItem(title: "❤️", action: nil, keyEquivalent: "") // 给根菜单设置唯一标识tag rootCustomItem.tag = kCustomRootMenuItemTag rootCustomItem.submenu = NSMenu(title: "") let watchMenuItem = NSMenuItem(title: "⌚️", action: nil, keyEquivalent: "") rootCustomItem.submenu?.addItem(watchMenuItem) let lightMenuItem = NSMenuItem(title: "💡", action: nil, keyEquivalent: "") rootCustomItem.submenu?.addItem(lightMenuItem) menu.addItem(rootCustomItem) // 注册菜单弹出监听,用于调整自定义菜单位置 NotificationCenter.default.addObserver( self, selector: #selector(adjustCustomMenuItemPosition(_:)), name: NSMenu.didBeginTrackingNotification, object: nil ) return menu }
实现位置调整的方法:
@objc private func adjustCustomMenuItemPosition(_ notification: Notification) { guard let targetMenu = notification.object as? NSMenu else { return } // 先定位到自定义的根菜单项 guard let customItem = targetMenu.items.first(where: { $0.tag == kCustomRootMenuItemTag }) else { return } // 先把自定义项从默认追加的末尾位置移除 customItem.menu?.removeItem(customItem) // 匹配New Folder菜单项:通过固定action匹配,兼容所有系统语言,比匹配title更稳定 guard let newFolderItemIndex = targetMenu.items.firstIndex(where: { $0.action == Selector(("newFolder:")) }) else { // 极端场景没找到新建文件夹项时,兜底放回菜单末尾 targetMenu.addItem(customItem) return } // 插入到新建文件夹项的正下方 targetMenu.insertItem(customItem, at: newFolderItemIndex + 1) // 移除通知监听,避免重复触发 NotificationCenter.default.removeObserver( self, name: NSMenu.didBeginTrackingNotification, object: nil ) }
注意:不要通过匹配菜单标题文本的方式查找「New Folder」项,该方式在非中文/英文的系统语言环境下会失效,通过系统固定的
newFolder:action匹配是兼容性最好的方案。
内容的提问来源于stack exchange,提问作者Huang Runhua
相关产品推荐
相关产品推荐

