Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 如何更改/修改NSPopUpButton的显示标题_Swift_Cocoa_Appkit - Fatal编程技术网

Swift 如何更改/修改NSPopUpButton的显示标题

Swift 如何更改/修改NSPopUpButton的显示标题,swift,cocoa,appkit,Swift,Cocoa,Appkit,我希望nspoupbutton显示与所选菜单项标题不同的标题 假设我有一个nspoupbutton,允许用户选择货币列表,如何让折叠/关闭按钮仅显示货币缩写而不是所选货币的菜单标题(即货币的全名) 我想我可以覆盖draw的一个子类(属于NSPopUpButtonCell)并自己绘制整个按钮,但我现在更喜欢一种更轻量级的方法,即重用系统的外观 菜单项包含有关缩写的必要信息,因此这不是问题的一部分。好的,因此我找到了如何修改标题的方法。我创建了一个cell子类,其中我覆盖了基于所选项目的标题设置。在

我希望
nspoupbutton
显示与所选菜单项标题不同的标题

假设我有一个
nspoupbutton
,允许用户选择货币列表,如何让折叠/关闭按钮仅显示货币缩写而不是所选货币的菜单标题(即货币的全名)

我想我可以覆盖draw的一个子类(属于
NSPopUpButtonCell
)并自己绘制整个按钮,但我现在更喜欢一种更轻量级的方法,即重用系统的外观


菜单项包含有关缩写的必要信息,因此这不是问题的一部分。

好的,因此我找到了如何修改标题的方法。我创建了一个cell子类,其中我覆盖了基于所选项目的标题设置。在我的例子中,我检查问题中讨论的表示对象

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 {}
    }
}
然后在button子类中设置单元格(我使用xibs)


但缺点是,我必须复制在Interface Builder中配置的单元格的所有属性。当然,我可以在Interface Builder中设置cell类,这样做是多余的

有一件事我还没有弄清楚我现在如何让按钮具有正确的固有内容大小。它仍然试图与最长的常规标题一样宽


第二件我还没有弄明白的事情是如何使用绑定实现这一点。如果按钮内容是通过Cocoa绑定提供的,那么我只能绑定contentValues,并且永远不会调用单元格的title属性。

子类
NSPopUpButtonCell
,覆盖
drawTitle(u1;: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)
}

您应该使用popupbuttoncell+“override func drawTitle(withFrame-cellFrame:NSRect,在controlView:NSView中)”的自定义子类,并从representedObject获取标题。它将只绘制选定的项目单元格,而不是菜单。我在问题中表示,我不想自己绘制文本。接受+为什么不能在XIB中为单元格使用自定义类(您可以在awakefromnib中复制它)在我的XIB中,我实际上设置了类,但没有在awakefromnib中进行设置。是的,我应该写下,这是一个平等的可能性。我不知道你说的“重新制作整个菜单”是什么意思。除了剩下的两点外,所提出的解决方案工作良好。关于这些要点中的哪一点?“但缺点是我必须复制我在Interface Builder中配置的单元格的所有属性。”-这令人困惑,也是我特别要求不要使用自定义绘图的部分问题答案。我不知道为什么你否决了我的答案,并发布了忽略我问题的答案…你的解决方案可能绝对有效,我很感激你用你的解决方案完成了这一页,但再次…我在哪里使用自定义绘图?好的,解释有点短,我会编辑它。我忽略了哪个问题?
drawTitle
方法正在绘制(我承认,我的措辞本可以更好),但我必须再次承认,也许我在这里完全错了,你是对的。嗯……我道歉。我被方法名中的
draw
蒙蔽了双眼。Pfff愚弄了我…我会在上面留下我的错误评论,感到羞愧
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)
}
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
}