Отображать только "Настроить панель инструментов..." в контекстном меню NSToolbar в Swift

Я знаю, что этот вопрос задавался много раз, но, кажется, лучшего решения для него нет.

Изменение allowsUserCustomization собственность не помогает. Кажется, что нет API для настройки элементов в контекстном меню панели инструментов.

В приложении Finder нет "Использовать малый размер", а в приложении "Примечания" есть только "Настроить панель инструментов...".

Я хотел бы знать, есть ли какой-либо способ создать подкласс, расширить или сделать что-нибудь для NSToolbar для достижения цели?

Обновлено 1:

Согласно @Khundragpan и этому посту, проблему 1 можно решить следующим образом:

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

Но я не думаю, что это лучший способ.

Обновление 2:

Еще один способ решить проблему 1 (спасибо @1024jp за указание этого файла):

    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 за помощь. Я могу удалить эти вещи с помощью нескольких советов и хитростей от него. Проверьте ответ ниже.

1 ответ

Решение

Через 3 дня я наконец сделал это. Вот результат.

введите описание изображения здесь

введите описание изображения здесь

Исходный код в Swift 3

Вы можете реализовать и создать свой собственный класс, но здесь я просто хочу сохранить все в файле.

Это WindowController.swift файл. Вы можете установить собственный класс вашего оконного контроллера и запустить. Еще раз спасибо @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
    }

}
Другие вопросы по тегам