swift - 在 Swift 中 NSToolbar 的上下文菜单中仅显示 "Customize Toolbar..."

标签 swift cocoa contextmenu swift3 nstoolbar

enter image description here

我知道这个问题已被问过很多次,但似乎没有更好的解决方案。

更改 allowsUserCustomization 属性没有帮助。似乎没有 API 可以自定义工具栏上下文菜单中的项目。

Finder 应用程序没有“使用小尺寸”,而 Notes 应用程序只有“自定义工具栏..”

我想知道是否有任何方法可以对 NSToolbar 进行子类化或扩展或执行任何操作来达到目的?

更新1:

根据 @Khundragpan 和 this post ,问题1可以通过以下方式解决:

    if let contextMenu = window?.contentView?.superview?.menu {
        for item in contextMenu.items {
            if item.title != "Customize Toolbar…" {
                contextMenu.removeItem(item)
            }
        }
    }

但我认为这不是最好的方法。

更新2:

解决问题1的另一种方法(感谢@1024jp指出this file):

    if let contextMenu = window?.contentView?.superview?.menu {
        contextMenu.items.forEach({ (item) in
            if let action = item.action,
                NSStringFromSelector(action) != "runToolbarCustomizationPalette:" {
                contextMenu.removeItem(item)
            }
        })
    }

更新3:

非常感谢@1024jp对我的帮助。我可以通过他的一些提示和技巧来删除这些东西。检查下面的答案。

最佳答案

三天后,我终于做到了。这是结果。

enter image description here

enter image description here

Swift 3 中的源代码

您可以实现并创建自己的类,但在这里我只想将所有内容都保存在文件中。

这是WindowController.swift 文件。您可以设置窗口 Controller 的自定义类并运行。再次感谢 @1024jp 的提示。

//
//  WindowController.swift
//  The Toolbar
//
//  Created by João Oliveira on 22/09/2016.
//  Copyright © 2016 João Oliveira. All rights reserved.
//

import Cocoa

class WindowController: NSWindowController {

    override func windowDidLoad() {
        super.windowDidLoad()

        guard let window = window else { return }

        window.delegate = self

        window.toolbar = NSToolbar(identifier: "RestrictedToolbar")
        window.toolbar?.allowsUserCustomization = true
        window.toolbar?.displayMode = .iconOnly
        window.toolbar?.delegate = self

        keepOnlyCustomizableMenu()
    }

    // PROBLEM 1: Solution
    func keepOnlyCustomizableMenu() {
        if let contextMenu = window?.contentView?.superview?.menu {
            contextMenu.items.forEach({ (item) in
                if let action = item.action,
                    NSStringFromSelector(action) != "runToolbarCustomizationPalette:" {
                    contextMenu.removeItem(item)
                }
            })
        }
    }
}

// MARK: Window Delegate
// A ton of thanks to genius @1024jp
extension MyWindowController: NSWindowDelegate {

    // PROBLEM 2: Solution
    func window(_ window: NSWindow, willPositionSheet sheet: NSWindow, using rect: NSRect) -> NSRect {

        if sheet.className == "NSToolbarConfigPanel" {
            removeSizeAndDisplayMode(in: sheet)
        }

        return rect
    }

    func removeSizeAndDisplayMode(in sheet: NSWindow) {

        guard let views = sheet.contentView?.subviews else { return }

        // Hide Small Size Option
        views.lazy
            .flatMap { $0 as? NSButton }
            .filter { button -> Bool in
                guard let buttonTypeValue = button.cell?.value(forKey: "buttonType") as? UInt,
                    let buttonType = NSButtonType(rawValue: buttonTypeValue)
                    else { return false }
                return buttonType == .switch
            }
            .first?.isHidden = true

        // Hide Display Mode Option
        views.lazy
            .filter { view -> Bool in
                return view.subviews.count == 2
            }
            .first?.isHidden = true

        sheet.contentView?.needsDisplay = true
    }

}

// MARK: Toolbar Delegate
extension MyWindowController: NSToolbarDelegate {

    func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [String] {
        return [
            NSToolbarFlexibleSpaceItemIdentifier,
            NSToolbarSpaceItemIdentifier,
            NSToolbarToggleSidebarItemIdentifier
        ]
    }

    func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [String] {
        return [NSToolbarToggleSidebarItemIdentifier]
    }

    func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: String, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? {
        return nil
    }

}

关于swift - 在 Swift 中 NSToolbar 的上下文菜单中仅显示 "Customize Toolbar...",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39622468/

相关文章:

wpf - 将菜单项添加到 FlowDocumentReader ContextMenu

ios - 当以编程方式设置 Root View Controller 时,导航和选项卡栏丢失

ios - 保存由 textFieldDidEndEditing 更改的文本字段值不会保存在核心数据中?

xcode - macOS 10.10 中的 UI 布局问题(适用于 macOS 10.12)

cocoa - NSTableView 可能无法响应 "_LocationOfColumn"

c++ - “send to”如何管理输入参数? ( Windows )

swift - 在 RealityKit 中导入多个 .usdz 对象并为其设置动画

swift - 无法将类型 'IndexPath' 的值分配给类型 'Int'

ios - GCD dispatch_async 是否等待 NSLog()?

java - 我的fragmentClass在medod onContextItemSelected中从ViewPager获取错误的页面