【问题标题】:Cocoa NSPopUpButtonCell not displaying selected valueCocoa NSPopUpButtonCell 不显示所选值
【发布时间】:2016-04-01 20:23:10
【问题描述】:

背景

我有一个包含 3 列的 NSTableView,其中一列有一个 NSPopUpButtonCell。

我未能成功使用数据绑定来填充单元格数据,因此我现在正在尝试一种新方法,即使用 addItemsWithTitles 以编程方式设置值。

虽然这种方法可以加载值,但它无法显示默认选择(我对我的数组的索引 0 没问题),并且它也无法显示我在弹出窗口中选择的任何项目。

绑定问题

文档建议使用绑定并提供使用 Core Data 在弹出窗口中加载关系数据的示例。尽管我的应用程序设置不同,但我仍然尝试使用数组控制器,但这不会填充 popUpButtoncell 中的数据。

我的数据结构是一个简单的类对象,没有核心数据,长这样。

class Display: NSObject {
    var name: String
    var resolution: String
    var availableResolutions: [String]
}

我想使用 availableResolutions 数组来填充下拉列表。

我表中的每一行都代表一个 Display 对象的实例。我希望 NSPopUpButtonCell 显示该特定显示器的可用解决方案列表中的项目。我不确定是否可以为每个显示行创建一个动态列表。

我的尝试

我为我的 NSPopUpButtonCell 创建了一个 IBOutlet,并在 objectValueForTableColumn 和 setObjectValue 中引用它。我在 objectValueForTableColumn 中添加了 availableResultions 数组。

@IBOutlet weak var popUpCell: NSPopUpButtonCell!

func numberOfRowsInTableView(tableView: NSTableView) -> Int {
    return self.displays.count
}

func tableView(tableView: NSTableView, objectValueForTableColumn tableColumn: NSTableColumn?, row: Int) -> AnyObject? {
    let display = displays[row]

    if tableColumn!.identifier == "displayCell" {
        return display.name
    }
    else if tableColumn!.identifier == "resolutionCell" {
        return display.resolution
    }
    else {
        self.popUpCell.addItemsWithTitles(display.availableResolutions!)
        return display.availableResolutions
    }
}

func tableView(tableView: NSTableView, setObjectValue object: AnyObject?, forTableColumn tableColumn: NSTableColumn?, row: Int) {

    if tableColumn!.identifier == "displayCell" {
        displays[row].name = object as! String
    }
    else if tableColumn!.identifier == "resolutionCell" {
        object as! String
    }
    else {
        let index = object as! Int
        if index >= 0 {
            self.popUpCell.selectItemAtIndex(index)
            self.popUpCell.synchronizeTitleAndSelectedItem()
        }
    }
}

我错过了什么?

【问题讨论】:

  • 你确定调用了 objectValueForTableColumn 和 setObjectValue 吗?这些不是用于基于单元格的表格视图吗?您很可能拥有基于视图的表格视图。
  • 内容模式设置为基于单元格。我可以确认 objectValueForTableColumn 被调用,因为实际上填充了其他列的数据。此外,如果我修改表中的任何数据,setObjectValue 会被调用并起作用。

标签: swift cocoa nstableview cocoa-bindings nspopupbuttoncell


【解决方案1】:

使用绑定:

将列的Selected Value绑定到arrangedObjectsresolution

将列的Content Values绑定到同一个数组控制器arrangedObjectsavailableResolutions

没有绑定:

数据源方法tableView:objectValueForTableColumn:row:tableView:setObjectValue:forTableColumn:row: 处理所选项目。委托方法tableView:dataCellForTableColumn:row: 处理项目。

func numberOfRowsInTableView(tableView: NSTableView) -> Int {
    return self.displays.count
}

func tableView(tableView: NSTableView, objectValueForTableColumn tableColumn: NSTableColumn?, row: Int) -> AnyObject? {
    let display = displays[row]
    if tableColumn!.identifier == "displayCell" {
        return display.name
    }
    else if tableColumn!.identifier == "resolutionCell" {
        return display.availableResolutions.indexOf(display.resolution)
    }
    return nil
}

func tableView(tableView: NSTableView, setObjectValue object: AnyObject?, forTableColumn tableColumn: NSTableColumn?, row: Int) {
    let display = displays[row]
    if tableColumn!.identifier == "displayCell" {
        display.name = object as! String
    }
    else if tableColumn!.identifier == "resolutionCell" {
        display.resolution = display.availableResolutions[object as! Int]
    }
}

func tableView(tableView: NSTableView, dataCellForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSCell? {
    if let cell = tableColumn?.dataCellForRow(row) as? NSCell {
        if tableColumn!.identifier == "resolutionCell" {
            if let popupButtonCell = cell as? NSPopUpButtonCell {
                popupButtonCell.removeAllItems()
                popupButtonCell.addItemsWithTitles(displays[row].availableResolutions)
            }
        }
        return cell
    }
    return nil
}

附言我对 Swift 不熟悉。

【讨论】:

  • 这为我指明了正确的方向。我需要在 objectValueForTableColumn 中返回 indexOf。首先我检查 display.availableResolutions.indexOf(display.resolution) 是否为零。如果是,则返回列表中的第一项,否则返回上述内容。谢谢!
猜你喜欢
  • 1970-01-01
  • 2013-02-04
  • 2012-10-10
  • 2011-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多