我希望NSPopUpButton
显示与所选菜单项标题不同的标题。
假设我有一个NSPopUpButton
让用户选择一个货币列表,我怎么能让折叠/关闭按钮只显示货币缩写而不是所选货币的菜单标题(这是完整的货币名称)?
我想我可以在子类(NSPopUpButtonCell
)中覆盖绘制并自己绘制整个按钮,但我现在更喜欢使用更轻量级的方法来重用系统的外观。
菜单项包含有关缩写的必要信息,因此这不是问题的一部分。
答案 0 :(得分:3)
子类NSPopUpButtonCell
,覆盖drawTitle(_:withFrame:in:)
并使用您想要的标题调用super
。
override func drawTitle(_ title: NSAttributedString, withFrame frame: NSRect, in controlView: NSView) -> NSRect {
var attributedTitle = title
if let popUpButton = self.controlView as? NSPopUpButton {
if let object = popUpButton.selectedItem?.representedObject as? Dictionary<String, String> {
if let shortTitle = object["shortTitle"] {
attributedTitle = NSAttributedString(string:shortTitle, attributes:title.attributes(at:0, effectiveRange:nil))
}
}
}
return super.drawTitle(attributedTitle, withFrame:frame, in:controlView)
}
以同样的方式,您可以覆盖intrinsicContentSize
的子类中的NSPopUpButton
。更换菜单,拨打super
并重新放回原始菜单。
override var intrinsicContentSize: NSSize {
if let popUpButtonCell = self.cell {
if let orgMenu = popUpButtonCell.menu {
let menu = NSMenu(title: "")
for item in orgMenu.items {
if let object = item.representedObject as? Dictionary<String, String> {
if let shortTitle = object["shortTitle"] {
menu.addItem(withTitle: shortTitle, action: nil, keyEquivalent: "")
}
}
}
popUpButtonCell.menu = menu
let size = super.intrinsicContentSize
popUpButtonCell.menu = orgMenu
return size
}
}
return super.intrinsicContentSize
}
答案 1 :(得分:-1)
好的,所以我发现了如何修改标题。我创建了一个单元子类,我在其中覆盖基于所选项目设置标题。在我的例子中,我按照问题中的讨论来检查所代表的对象。
final class MyPopUpButtonCell: NSPopUpButtonCell {
override var title: String! {
get {
guard let selectedCurrency = selectedItem?.representedObject as? ISO4217.Currency else {
return selectedItem?.title ?? ""
}
return selectedCurrency.rawValue
}
set {}
}
}
然后在我的按钮子类中设置单元格(我使用xibs)
override func awakeFromNib() {
guard let oldCell = cell as? NSPopUpButtonCell else { return }
let newCell = MyPopUpButtonCell()
newCell.menu = oldCell.menu
newCell.bezelStyle = oldCell.bezelStyle
newCell.controlSize = oldCell.controlSize
newCell.autoenablesItems = oldCell.autoenablesItems
newCell.font = oldCell.font
cell = newCell
}
但缺点是我必须复制我在Interface Builder中配置的单元格的所有属性。我当然可以在Interface Builder中设置单元格类,这使得这一点变得多余。 / p>
我还没想到的一件事是我现在可以让按钮具有正确的内在内容大小。它仍然试图像最长的常规冠军一样宽。
我还没想到的第二件事是如何使用绑定工作。如果按钮内容是通过Cocoa Bindings提供的,那么我只能绑定contentValues,并且永远不会调用单元格的title属性。