Joã*_*ira 2 cocoa contextmenu nstoolbar swift swift3
I know this question has been asked many times but it seems no better solution for it.
Changing the allowsUserCustomization property doesn't help. It seems there is no API to customize the items in toolbar's context menu.
Finder app has no "Use Small Size" while Notes app has only "Customize Toolbar.."
I would like to know if there is any way to subclass or extend or do whatever to the NSToolbar to achieve the purpose?
Updated 1:
According to @Khundragpan and this post, problem 1 can be solved by:
if let contextMenu = window?.contentView?.superview?.menu {
for item in contextMenu.items {
if item.title != "Customize Toolbar…" {
contextMenu.removeItem(item)
}
}
}
Run Code Online (Sandbox Code Playgroud)
But I don't think it's the best way.
Update 2:
Another way to solve problem 1 (thanks to @1024jp to point out 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)
}
})
}
Run Code Online (Sandbox Code Playgroud)
Update 3:
A ton of thanks to @1024jp for helping me. I'm able to remove those things with a few tips and tricks from him. Check the answer below.
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
}
}
Run Code Online (Sandbox Code Playgroud)