我在 AppKit 应用程序中使用自定义视图以编程方式创建了一些
NSToolbarItem
。工具栏项目在工具栏中显示(并运行)正常。自定义工具栏时会出现问题。
带有
NSToolbarItem
子类自定义视图的 NSView
确实会在工具栏和 "... 中呈现,或者将默认设置拖到自定义面板的工具栏" 区域(底部),但不在 中“将您最喜欢的项目拖到工具栏...” 自定义面板区域(顶部)。相同的代码生成所有 3 个 NSToolbarItem
实例。
使用 NSButton
、
NSTextField
和其他控件作为自定义视图的工具栏项目在所有情况下都会呈现,但基于
NSView
的工具栏项目不会呈现。我需要做什么才能使基于 NSView
的自定义工具栏项在自定义工具栏窗格的两个区域中都可见?
这是
NSWindowController
的简化版本,它创建工具栏(并充当工具栏的代理)
import AppKit
public class DocumentWindowController : NSWindowController, NSToolbarDelegate {
private struct ToolbarItemIdentifiers {
fileprivate static let addPhotos = NSToolbarItem.Identifier("add-photos")
fileprivate static let thumbnailSize = NSToolbarItem.Identifier("thumbnail-size")
}
public override init (
window: NSWindow?
) {
super.init(window: window)
let toolbar = NSToolbar(identifier: "toolbar-identifier.document")
toolbar.delegate = self
toolbar.allowsUserCustomization = true
toolbar.autosavesConfiguration = true
toolbar.displayMode = .default
window?.toolbarStyle = .unified
window?.titleVisibility = .visible
window?.toolbar = toolbar
}
// MARK: - NSToolbarDelegate
public func toolbar (
_ toolbar: NSToolbar,
itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier,
willBeInsertedIntoToolbar flag: Bool
) -> NSToolbarItem? {
switch itemIdentifier {
case ToolbarItemIdentifiers.addPhotos:
let toolbarItem = NSToolbarItem(itemIdentifier: itemIdentifier)
toolbarItem.label = "Add Photos"
toolbarItem.image = NSImage(systemSymbolName: "plus", accessibilityDescription: "Add Photos Icon")
toolbarItem.target = self
toolbarItem.action = #selector(self.addPhotosButtonTapped)
return toolbarItem
case ToolbarItemIdentifiers.thumbnailSize:
let toolbarItem = NSToolbarItem(itemIdentifier: itemIdentifier)
toolbarItem.label = "Thumbnail Size"
toolbarItem.view = ThumbnailSizeView() // an unremarkable NSView subclass
return toolbarItem
default:
return nil
}
}
public func toolbarAllowedItemIdentifiers (_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
return [
ToolbarItemIdentifiers.addPhotos,
ToolbarItemIdentifiers.thumbnailSize
]
}
public func toolbarDefaultItemIdentifiers (_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
return [
ToolbarItemIdentifiers.addPhotos,
ToolbarItemIdentifiers.thumbnailSize
]
}
}
class ThumbnailSizeView : NSView {
private let slider = NSSlider()
init(min minValue: Int64, max maxValue: Int64, initial initialValue: Int64) {
super.init(frame: .zero)
let minusIcon = NSImageView()
minusIcon.image = NSImage(
systemSymbolName: "minus",
accessibilityDescription: "Smaller"
)?.withSymbolConfiguration(.init(scale: .small))
minusIcon.translatesAutoresizingMaskIntoConstraints = false
minusIcon.setContentCompressionResistancePriority(.required, for: .horizontal)
minusIcon.setContentHuggingPriority(.required, for: .horizontal)
addSubview(minusIcon)
NSLayoutConstraint.activate([
minusIcon.leadingAnchor.constraint(equalTo: leadingAnchor),
minusIcon.centerYAnchor.constraint(equalTo: centerYAnchor)
])
slider.minValue = Double(minValue)
slider.maxValue = Double(maxValue)
slider.intValue = Int32(initialValue)
slider.sliderType = .linear
slider.controlSize = .mini
slider.translatesAutoresizingMaskIntoConstraints = false
addSubview(slider)
NSLayoutConstraint.activate([
slider.leadingAnchor.constraint(equalTo: minusIcon.trailingAnchor, constant: 4),
slider.centerYAnchor.constraint(equalTo: centerYAnchor),
slider.widthAnchor.constraint(equalToConstant: 66)
])
let plusIcon = NSImageView()
plusIcon.image = NSImage(
systemSymbolName: "plus",
accessibilityDescription: "Larger"
)?.withSymbolConfiguration(.init(scale: .small))
plusIcon.translatesAutoresizingMaskIntoConstraints = false
plusIcon.setContentCompressionResistancePriority(.required, for: .horizontal)
plusIcon.setContentHuggingPriority(.required, for: .horizontal)
addSubview(plusIcon)
NSLayoutConstraint.activate([
plusIcon.leadingAnchor.constraint(equalTo: slider.trailingAnchor, constant: 4),
plusIcon.centerYAnchor.constraint(equalTo: centerYAnchor),
plusIcon.trailingAnchor.constraint(equalTo: trailingAnchor)
])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
就上下文而言,我在 macOS Ventura 13.5.1 上使用 Xcode 14.3.1
不久前我也遇到了类似的问题...我认为我的情况的修复方法是不总是在工具栏中返回一个新的 NSToolbarItem:itemForItemIdentifier:willBeInsertedIntoToolbar: 而是根据标识符缓存它们并始终返回相同的。自定义面板的副本是通过其他方式在内部创建的......