- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我很难将自定义 NSToolbarItem 添加到我现有的工具栏。
NSToolbar 是在 NSWindowController 中创建的,然后我有一个以编程方式填充工具栏项的函数,代码如下:
public func populateFileToolbarItem(_ toolbar: NSToolbar) -> Void{
let itemId = NSToolbarItem.Identifier("FILE_OPEN")
let index = toolbar.items.count
var toolbarItem: NSToolbarItem
toolbarItem = NSToolbarItem(itemIdentifier: itemId)
toolbarItem.label = String("File")
toolbarItem.paletteLabel = String("Open File")
toolbarItem.toolTip = String("Open file to be handled")
toolbarItem.tag = index
toolbarItem.target = self
toolbarItem.isEnabled = true
toolbarItem.action = #selector(browseFile)
toolbarItem.image = NSImage.init(named:NSImage.folderName)
toolbar.insertItem(withItemIdentifier: itemId, at: index)
}
然后我调用此函数将工具栏项添加到 windowController 中的现有工具栏
.......
populateFileToolbarItem((self.window?.toolbar)!)
self.window?.toolbar?.insertItem(withItemIdentifier: NSToolbarItem.Identifier.flexibleSpace, at: (self.window?.toolbar?.items.count)!)
self.window?.toolbar?.insertItem(withItemIdentifier: NSToolbarItem.Identifier.print, at: (self.window?.toolbar?.items.count)!)
print("after toolbaritems were inserted into toolbar. \(String(describing: self.window?.toolbar?.items.count))")
......
控制台打印显示,只有两个工具栏项被添加到工具栏。
.......
after toolbaritems were inserted into toolbar. Optional(2)
并且工具栏中没有显示自定义项。
哪位有经验的,请指教!
最佳答案
要从工具栏添加/删除项目,您需要工具栏委托(delegate):NSToolbarDelegate。
这是我正在使用的实现模板(可能比您想要的更多)。
用于创建各种类型的工具栏项的样板代码:
struct ToolbarIdentifiers {
static let mainToolbar = NSToolbar.Identifier(stringLiteral: "MainToolbar")
static let navGroupItem = NSToolbarItem.Identifier(rawValue: "NavGroupToolbarItem")
static let shareItem = NSToolbarItem.Identifier(rawValue: "ShareToolBarItem")
static let addItem = NSToolbarItem.Identifier(rawValue: "AddToolbarItem")
static let statusItem = NSToolbarItem.Identifier(rawValue: "StatusToolbarItem")
static let filterItem = NSToolbarItem.Identifier(rawValue: "FilterToolbarItem")
static let sortItem = NSToolbarItem.Identifier(rawValue: "SortToolbarItem")
static let cloudUploadItem = NSToolbarItem.Identifier(rawValue: "UploadToolbarItem")
static let cloudDownloadItem = NSToolbarItem.Identifier(rawValue: "DownloadToolbarItem")
static let leftButtonItem = NSToolbarItem.Identifier(rawValue: "leftButtonToolbarItem")
static let rightButtonItem = NSToolbarItem.Identifier(rawValue: "rightButtonToolbarItem")
static let hideShowItem = NSToolbarItem.Identifier(rawValue: "hideShowToolbarItem")
}
// Base toolbar item type, extended for segmented controls, buttons, etc.
struct ToolbarItem {
let identifier: NSToolbarItem.Identifier
let label: String
let paletteLabel: String
let tag: ToolbarTag
let image: NSImage?
let width: CGFloat
let height: CGFloat
let action: Selector?
weak var target: AnyObject?
var menuItem: NSMenuItem? = nil // Needs to be plugged in after App has launched.
let group: [ToolbarItem]
init(_ identifier: NSToolbarItem.Identifier, label: String = "", tag: ToolbarTag = .separator, image: NSImage? = nil,
width: CGFloat = 38.0, height: CGFloat = 28.0,
action: Selector? = nil, target: AnyObject? = nil, group: [ToolbarItem] = [], paletteLabel: String = "") {
self.identifier = identifier
self.label = label
self.paletteLabel = paletteLabel
self.tag = tag
self.width = width
self.height = height
self.image = image
self.action = action
self.target = target
self.group = group
}
}
// Image button -- creates NSToolbarItem
extension ToolbarItem {
func imageButton() -> NSToolbarItem {
let item = NSToolbarItem(itemIdentifier: identifier)
item.label = label
item.paletteLabel = label
item.menuFormRepresentation = menuItem // Need this for text-only to work
item.tag = tag.rawValue
let button = NSButton(image: image!, target: target, action: action)
button.widthAnchor.constraint(equalToConstant: width).isActive = true
button.heightAnchor.constraint(equalToConstant: height).isActive = true
button.title = ""
button.imageScaling = .scaleProportionallyDown
button.bezelStyle = .texturedRounded
button.tag = tag.rawValue
button.focusRingType = .none
item.view = button
return item
}
}
// Segmented control -- creates NSToolbarItemGroup containing multiple instances of NSToolbarItem
extension ToolbarItem {
func segmentedControl() -> NSToolbarItemGroup {
let itemGroup = NSToolbarItemGroup(itemIdentifier: identifier)
let control = NSSegmentedControl(frame: NSRect(x: 0, y: 0, width: width, height: height))
control.segmentStyle = .texturedSquare
control.trackingMode = .momentary
control.segmentCount = group.count
control.focusRingType = .none
control.tag = tag.rawValue
var items = [NSToolbarItem]()
var iSeg = 0
for segment in group {
let item = NSToolbarItem(itemIdentifier: segment.identifier)
items.append(item)
item.label = segment.label
item.tag = segment.tag.rawValue
item.action = action
item.target = target
control.action = segment.action // button & container send to separate handlers
control.target = segment.target
control.setImage(segment.image, forSegment: iSeg)
control.setImageScaling(.scaleProportionallyDown, forSegment: iSeg)
control.setWidth(segment.width, forSegment: iSeg)
control.setTag(segment.tag.rawValue, forSegment: iSeg)
iSeg += 1
}
itemGroup.paletteLabel = paletteLabel
itemGroup.subitems = items
itemGroup.view = control
return itemGroup
}
}
// Text field -- creates NSToolbarItem containing NSTextField
extension ToolbarItem {
func textfieldItem() -> NSToolbarItem {
let item = NSToolbarItem(itemIdentifier: identifier)
item.label = ""
item.paletteLabel = label
item.tag = tag.rawValue
let field = NSTextField(string: label)
field.widthAnchor.constraint(equalToConstant: width).isActive = true
field.heightAnchor.constraint(equalToConstant: height).isActive = true
field.tag = tag.rawValue
field.isSelectable = false
item.view = field
return item
}
}
// Menu item -- creates an empty NSMenuItem so that user can click on the label
// definitely a work-around till we implement the menus
extension ToolbarItem {
mutating func createMenuItem(_ action: Selector) {
let item = NSMenuItem()
item.action = action
item.target = target
item.title = label
item.tag = tag.rawValue
self.menuItem = item
}
}
/*
* Create specialized toolbar items with graphics, labels, actions, etc
* Encapsulates implementation-specific details in code, because the table-driven version was hard to read.
*/
struct InitializeToolbar {
}
extension InitializeToolbar {
static func navGroupItem(_ action: Selector, segmentAction: Selector, target: AnyObject) -> ToolbarItem {
var group = [ToolbarItem]()
group.append(ToolbarItem(NSToolbarItem.Identifier(rawValue: "BackToolbarItem"), label: "Prev", tag: .navPrev,
image: NSImage(named: NSImage.goBackTemplateName), action: segmentAction, target: target))
group.append(ToolbarItem(NSToolbarItem.Identifier(rawValue: "FwdToolbarItem"), label: "Next", tag: .navNext,
image: NSImage(named: NSImage.goForwardTemplateName), action: segmentAction, target: target))
let item = ToolbarItem(ToolbarIdentifiers.navGroupItem, tag: .navGroup, width: 85, height: 28,
action: action, target: target, group: group, paletteLabel: "Navigation")
return item
}
}
extension InitializeToolbar {
static func hideShowItem(_ action: Selector, segmentAction: Selector, target: AnyObject) -> ToolbarItem {
var group = [ToolbarItem]()
group.append(ToolbarItem(NSToolbarItem.Identifier(rawValue: "HideLeftItem"), label: "", tag: .leftButton,
image: NSImage(named: "leftButton"), action: segmentAction, target: target))
group.append(ToolbarItem(NSToolbarItem.Identifier(rawValue: "HideRightItem"), label: "", tag: .rightButton,
image: NSImage(named: "rightButton"), action: segmentAction, target: target))
let item = ToolbarItem(ToolbarIdentifiers.hideShowItem, tag: .hideShow, width: 85, height: 28,
action: action, target: target, group: group, paletteLabel: "Hide/Show")
return item
}
}
extension InitializeToolbar {
static func addItem(_ action: Selector, target: AnyObject) -> ToolbarItem {
let item = ToolbarItem(ToolbarIdentifiers.addItem, label: "Add", tag: .add, image: NSImage(named: NSImage.addTemplateName), action: action, target: target)
return item
}
}
extension InitializeToolbar {
static func shareItem(_ action: Selector, target: AnyObject) -> ToolbarItem {
let item = ToolbarItem(ToolbarIdentifiers.shareItem, label: "Share", tag: .share, image: NSImage(named: NSImage.shareTemplateName), action: action, target: target)
return item
}
}
extension InitializeToolbar {
static func filterItem(_ action: Selector, target: AnyObject) -> ToolbarItem {
let item = ToolbarItem(ToolbarIdentifiers.filterItem, label: "Filter", tag: .filter, image: NSImage(named: "filter"), action: action, target: target)
return item
}
}
extension InitializeToolbar {
static func sortItem(_ action: Selector, target: AnyObject) -> ToolbarItem {
let item = ToolbarItem(ToolbarIdentifiers.sortItem, label: "Sort", tag: .sort, image: NSImage(named: "sort"), action: action, target: target)
return item
}
}
extension InitializeToolbar {
static func cloudDownloadItem(_ action: Selector, target: AnyObject) -> ToolbarItem {
let item = ToolbarItem(ToolbarIdentifiers.cloudDownloadItem, label: "Down", tag: .cloudDownload, image: NSImage(named: "cloudDownload"), action: action, target: target)
return item
}
}
extension InitializeToolbar {
static func cloudUploadItem(_ action: Selector, target: AnyObject) -> ToolbarItem {
let item = ToolbarItem(ToolbarIdentifiers.cloudUploadItem, label: "Up", tag: .cloudUpload, image: NSImage(named: "cloudUpload"), action: action, target: target)
return item
}
}
extension InitializeToolbar {
static func leftButtonItem(_ action: Selector, target: AnyObject) -> ToolbarItem {
let item = ToolbarItem(ToolbarIdentifiers.leftButtonItem, label: "", tag: .leftButton, image: NSImage(named: "leftButton"), action: action, target: target)
return item
}
}
extension InitializeToolbar {
static func rightButtonItem(_ action: Selector, target: AnyObject) -> ToolbarItem {
let item = ToolbarItem(ToolbarIdentifiers.rightButtonItem, label: "", tag: .rightButton, image: NSImage(named: "rightButton"), action: action, target: target)
return item
}
}
extension InitializeToolbar {
static func textItem() -> ToolbarItem {
return ToolbarItem(ToolbarIdentifiers.statusItem, label: "Watch This Space", tag: .status, width: 300, height: 24)
}
}
这是工具栏类,它实现了初始化器和委托(delegate):
/*
* Initializer builds a specialized toolbar.
*/
enum ToolbarTag: Int {
case separator = 1
case navGroup
case navPrev
case navNext
case add
case share
case filter
case sort
case cloudDownload
case cloudUpload
case leftButton
case rightButton
case hideShow
case status
}
class Toolbar: NSObject, NSToolbarDelegate, Actor {
var actorDelegate: ActorDelegate?
var identifier: NSUserInterfaceItemIdentifier?
var toolbarItemList = [ToolbarItem]()
var toolbarItemIdentifiers: [NSToolbarItem.Identifier] { return toolbarItemList.map({ $0.identifier }) }
var toolbarDefaultItemList = [ToolbarItem]()
var toolbarDefaultItemIdentifiers: [NSToolbarItem.Identifier] { return toolbarDefaultItemList.map({ $0.identifier }) }
// Delegate toolbar actions
@objc func controlSentAction(_ sender: Any) {
guard let control = sender as? NSControl else { return }
guard let tag = ToolbarTag(rawValue: control.tag) else { return }
actorDelegate?.actor(self, initiator: control, tag: tag, obj: nil)
}
@objc func segmentedControlSentAction(_ sender: Any) {
guard let segmented = sender as? NSSegmentedControl else { return }
guard let tag = ToolbarTag(rawValue: segmented.tag(forSegment: segmented.selectedSegment)) else { return }
actorDelegate?.actor(self, initiator: segmented, tag: tag, obj: nil)
}
// These don't get called at the moment
@objc func toolbarItemSentAction(_ sender: Any) { ddt("toolbarItemSentAction") }
@objc func menuSentAction(_ sender: Any) { ddt("menuSentAction") }
// Toolbar initialize
init(_ window: Window) {
super.init()
identifier = Identifier.View.toolbar
let toolbar = NSToolbar(identifier: ToolbarIdentifiers.mainToolbar)
toolbar.centeredItemIdentifier = ToolbarIdentifiers.statusItem
// Build the initial toolbar
// Text field
toolbarItemList.append(ToolbarItem(.flexibleSpace))
toolbarItemList.append(InitializeToolbar.textItem())
toolbarItemList.append(ToolbarItem(.flexibleSpace))
// Show/Hide
toolbarItemList.append(InitializeToolbar.hideShowItem(#selector(toolbarItemSentAction), segmentAction: #selector(segmentedControlSentAction), target: self))
// Save initial toolbar as default
toolbarDefaultItemList = toolbarItemList
// Also allow these, just to demo adding
toolbarItemList.append(InitializeToolbar.cloudDownloadItem(#selector(controlSentAction), target: self))
toolbarItemList.append(InitializeToolbar.sortItem(#selector(controlSentAction), target: self))
toolbar.allowsUserCustomization = true
toolbar.displayMode = .default
toolbar.delegate = self
window.toolbar = toolbar
}
deinit {
ddt("deinit", caller: self)
}
}
/*
* Implement NSToolbarDelegate
*/
extension Toolbar {
// Build toolbar
func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? {
guard let item = toolbarItemList.firstIndex(where: { $0.identifier == itemIdentifier }) else { return nil }
switch toolbarItemList[item].identifier {
case ToolbarIdentifiers.navGroupItem, ToolbarIdentifiers.hideShowItem:
return toolbarItemList[item].segmentedControl()
case ToolbarIdentifiers.addItem, ToolbarIdentifiers.shareItem, ToolbarIdentifiers.sortItem, ToolbarIdentifiers.filterItem, ToolbarIdentifiers.cloudUploadItem, ToolbarIdentifiers.cloudDownloadItem,
ToolbarIdentifiers.leftButtonItem, ToolbarIdentifiers.rightButtonItem:
return toolbarItemList[item].imageButton()
case ToolbarIdentifiers.statusItem:
return toolbarItemList[item].textfieldItem()
default:
return nil
}
} // end of toolbar
func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
return toolbarDefaultItemIdentifiers;
}
func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
return toolbarItemIdentifiers
}
func toolbarSelectableItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
return []
}
func toolbarWillAddItem(_ notification: Notification) {
}
func toolbarDidRemoveItem(_ notification: Notification) {
}
} // End of extension
初始工具栏:
自定义下拉菜单,Cocoa 为您做的:
添加云按钮后:
添加以澄清 2019 年 4 月 28 日:
我的工具栏类不是 NSToolbar 的子类。它的初始化程序传递了一个对窗口的引用,所以最后它将窗口的工具栏设置为它创建的工具栏:
init(_ window: Window) {
super.init()
identifier = Identifier.View.toolbar
**** stuff removed for clarity ****
let toolbar = NSToolbar(identifier: ToolbarIdentifiers.mainToolbar)
toolbar.allowsUserCustomization = true
toolbar.displayMode = .default
toolbar.delegate = self
window.toolbar = toolbar
}
也许这会混淆语义,但它会创建工具栏并充当工具栏委托(delegate),如您在扩展中所见。
“Actor”协议(protocol)是我协调框架的一部分,对于构建工具栏本身并不重要。我将不得不包括整个演示应用程序来展示这一点,并且我假设您有自己的设计来将工具栏操作传递给您的 Controller /模型。
此应用程序是 Xcode 10.2/Swift 5,但我认为它没有使用任何新的 Swift 5 功能。
关于swift - 如何以编程方式将自定义 NSToolbarItem 添加到现有工具栏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55878224/
有没有办法在 .swift 文件(编译成 .swift 模块)中声明函数,如下所示: 你好.swift func hello_world() { println("hello world")
我正在尝试使用 xmpp_messenger_ios 和 XMPPFramework 在 iOS 上执行 MUC 这是加入房间的代码。 func createOrJoinRoomOnXMPP()
我想在我的应用程序上创建一个 3D Touch 快捷方式,我已经完成了有关快捷方式本身的所有操作,它显示正确,带有文本和图标。 当我运行这个快捷方式时,我的应用程序崩溃了,因为 AppDelegate
我的代码如下: let assetTag = Expression("asset_tag") let query2 = mdm.select(mdm[assetTag],os, mac, lastRe
我的 swift 代码如下所示 Family.arrayTuple:[(String,String)]? = [] Family.arrayTupleStorage:String? Family.ar
这是我的 JSON,当我读取 ord 和 uniq 数据时出现错误 let response2 : [String: Any] = ["Response":["status":"SUCCESS","
我想将 swift 扩展文件移动到 swift 包中。但是,将文件移动到 swift 包后,我遇到了这种错误: "Type 'NSAttributedString' has no member 'ma
使用CocoaPods,我们可以设置以下配置: pod 'SourceModel', :configurations => ['Debug'] 有什么方法可以用 Swift Package Manag
我正在 Xcode 中开发一个 swift 项目。我将其称为主要项目。我大部分都在工作。我在日期选择器、日期范围和日期数学方面遇到了麻烦,因此我开始了另一个名为 StarEndDate 的项目,其中只
这是 ObjectiveC 代码: CCSprite *progress = [CCSprite spriteWithImageNamed:@"progress.png"]; mProgressBar
我正在创建一个命令行工具,在 Xcode 中使用 Swift。我想使用一个类似于 grunt 的配置文件确实如此,但我希望它是像 Swift 包管理器的 package.swift 文件那样的快速代码
我假设这意味着使用系统上安装的任何 swift 运行脚本:#!/usr/bin/swift 如何指定脚本适用的解释器版本? 最佳答案 Cato可用于此: #!/usr/bin/env cato 1.2
代码说完全没问题,没有错误,但是当我去运行模拟器的时候,会出现这样的字样: (Swift.LazyMapCollection (_base:[ ] 我正在尝试创建一个显示报价的报价应用。 这是导入
是否可以在运行 Swift(例如 Perfect、Vapor、Kitura 等)的服务器上使用 RealmSwift 并使用它来存储数据? (我正在考虑尝试将其作为另一种解决方案的替代方案,例如 no
我刚开始学习编程,正在尝试完成 Swift 编程书中的实验。 它要求““编写一个函数,通过比较两个 Rank 值的原始值来比较它们。” enum Rank: Int { case Ace = 1 ca
在您将此问题标记为重复之前,我检查了 this question 它对我不起作用。 如何修复这个错误: error: SWIFT_VERSION '5.0' is unsupported, suppo
从 Xcode 9.3 开始,我在我的模型中使用“Swift.ImplicitlyUnwrappedOptional.some”包裹了我的字符串变量 我不知道这是怎么发生的,但它毁了我的应用程序! 我
这个问题在这里已经有了答案: How to include .swift file from other .swift file in an immediate mode? (2 个答案) 关闭 6
我正在使用 Swift Package Manager 创建一个应用程序,我需要知道构建项目的配置,即 Debug 或 Release。我试图避免使用 .xcodeproj 文件。请有人让我知道这是否
有一个带有函数定义的文件bar.swift: func bar() { println("bar") } 以及一个以立即模式运行的脚本foo.swift: #!/usr/bin/xcrun s
我是一名优秀的程序员,十分优秀!