2016-09-21 1 views
0

enter image description hereПоказать только «Настройка панели инструментов ...» в контекстном меню NSToolbar в Swift

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

Изменение свойства 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) 
      } 
     } 
    } 

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

Update 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) 
      } 
     }) 
    } 

Update 3:

Тонна спасибо до @ 1024jp за помощь. Я могу удалить эти вещи с помощью нескольких советов и трюков от него. Проверьте ответ ниже.

+0

проверить эту ссылку http://stackoverflow.com/questions/8413111/how-to-customize-the-context-menu-of-nstoolbar – Khundragpan

+1

вы можете получить на панели инструментов меню с помощью 'пусть toolBarMenu = окно? .contentView? .superview? .menu'. Теперь удалите пункты меню, которые вы не хотите. – Khundragpan

+0

@Khundragpan Спасибо! Но это не решает проблему 2-го (ссылаясь на изображение). И я не думаю, что это правильный способ справиться с этим. –

ответ

2

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

enter image description here

enter image description here

Исходный код в 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 
    } 

} 
Смежные вопросы