2016-04-01 19 views
0

HintergrundCocoa NSPopUpButtonCell nicht ausgewählten Wert anzeigt

Ich habe eine NSTableView mit 3 Spalten, einer von ihnen eine NSPopUpButtonCell hat.

Ich war nicht erfolgreich bei der Verwendung von Datenbindungen, um die Zellendaten zu füllen, als solche versuche ich jetzt einen neuen Ansatz durch programmgesteuert setzen von Werten mit addItemsWithTitles.

Während dieser Ansatz funktioniert, um die Werte zu laden, ist es nicht möglich, den Standard ausgewählt anzuzeigen (ich bin okay mit Index 0 meines Arrays) und es ist auch nicht angezeigt, ein Element, das ich im Popup auswählen.

Bindungen Ausgabe

Die Dokumentationen vorschlagen Bindungen und geben ein Beispiel unter Verwendung von Core Data mit relationalen Daten im Popup zu laden. Obwohl meine App anders eingerichtet ist, habe ich immer noch versucht, einen Array-Controller zu verwenden, aber dies würde die Daten in der popUpButton-Zelle nicht füllen.

Meine Datenstruktur ist ein einfaches Klassenobjekt, keine Kerndaten, und es sieht so aus.

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

Ich möchte die availableResolutions Array verwenden, um die Drop-Down-aufzufüllen.

Jede Zeile in meiner Tabelle repräsentiert eine Instanz des Anzeigeobjekts. Ich möchte, dass NSPopUpButtonCell die Elemente in der Liste der availableResolutions des jeweiligen Displays anzeigt. Ich bin mir nicht sicher, ob es sogar möglich ist, für jede Zeile eine dynamische Liste zu erstellen.

Was ich versucht habe

Ich habe ein IBOutlet für meine NSPopUpButtonCell und ich bin Referenzierung es in objectValueForTableColumn und setObjectValue. Ich füge das Array von availableResultions innerhalb von objectValueForTableColumn hinzu.

@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() 
     } 
    } 
} 

Was fehlt mir?

+0

Sind Sie sicher, dass objectValueForTableColumn und setObjectValue aufgerufen werden? Sind das nicht zellbasierte Tabellenansichten? Sie haben wahrscheinlich eine view-basierte Tabellenansicht. – user965972

+0

Der Inhaltsmodus ist für zellenbasiert eingerichtet. Ich kann bestätigen objectValueForTableColumn aufgerufen wird, da die Daten für andere Spalten tatsächlich gefüllt sind.Außerdem wird setObjectValue aufgerufen und funktioniert, wenn ich die Daten in der Tabelle ändere. –

Antwort

0

mit Bindung:

Bind Selected Value der Säule arrangedObjects, resolution.

Binden Sie Content Values der Spalte an den gleichen Array-Controller, arrangedObjects, availableResolutions.

Ohne Bindungen:

Die Datenquelle Methoden tableView:objectValueForTableColumn:row: und tableView:setObjectValue:forTableColumn:row: Deal mit dem gewählten Artikel. Die Delegate-Methode tableView:dataCellForTableColumn:row: befasst sich mit den Elementen.

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 
} 

p.s. Ich bin nicht vertraut mit Swift.

+0

Dies wies mich in die richtige Richtung. Ich musste das indexOf in objectValueForTableColumn zurückgeben. Zuerst überprüfe ich, ob display.availableResolutions.indexOf (display.resolution) gleich null ist. Wenn es dann ist, gebe ich das erste Element in der Liste zurück, ansonsten gebe ich das obige zurück. Vielen Dank! –