2016-09-21 73 views
0

enter image description here顯示只有斯威夫特

在NSToolbar的上下文菜單「自定義工具欄...」我知道這個問題已經被問了很多次,但似乎沒有更好的解決方案了。

更改allowsUserCustomization屬性沒有幫助。似乎沒有API來自定義工具欄上下文菜單中的項目。

搜索的應用程序有沒有「使用小尺寸」,同時注意應用只有「自定義工具欄。」

我想知道是否有任何的方式來繼承或延長或做任何的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幫助我。我能夠從他的一些技巧和竅門中刪除這些東西。檢查下面的答案。

+0

檢查此鏈接http://stackoverflow.com/questions/8413111/how-to-customize-the-context-menu-of-nstoolbar – Khundragpan

+1

你可以通過'讓toolBarMenu =窗口工具欄菜單? .contentView?.superview?.menu'。現在刪除你不想要的菜單項。 – Khundragpan

+0

@Khundragpan謝謝!但這並不能解決第二個問題(指圖像)的問題。我不認爲這是處理這些問題的正確方法。 –

回答

2

3天后,我終於做到了。結果如下。

enter image description here

enter image description here

源代碼,斯威夫特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 
    } 

}