Frage

Ich möchte dynamisch verstecken / einige der Spalten in einer NSTableView zeigen, basierend auf den Daten, die angezeigt werden wird - im Grunde, wenn eine Spalte leer ist, ich die Spalte versteckt werden möchten. Ich bin derzeit die Tabelle mit einem Controller-Klasse als Delegierter für die Tabelle bevölkern.

Irgendwelche Ideen? Ich sehe, dass ich die Spalte versteckt in Interface Builder gesetzt, aber es scheint nicht eine gute Zeit, um die Spalten zu gehen und überprüfen, ob sie leer sind oder nicht, da es keine Methode zu sein scheint, das ist genannt vor / nach aufgefüllt wird alle Daten in der Tabelle.

War es hilfreich?

Lösung

Ein NSTable ist nur die Klasse, die die Tabelle malt. Wie Sie selbst gesagt, haben Sie einige Klassen, die Sie in der Tabelle als Delegierten geben und diese Klasse-Feeds mit den Daten in die Tabelle anzuzeigen. Wenn Sie die Tabellendaten als NSArray innerhalb Ihres Delegierten Klasse speichern, sollte es einfach sein, um herauszufinden, ob eine Spalte leer ist, ist es nicht? Und NSArray fragt Ihre Klasse über delegierte Methode, wie viele Spalten gibt es, also, wenn Sie gefragt werden, warum nicht auf der Suche nach, wie viele Spalten Sie Daten haben und berichten diese Nummer statt der tatsächlichen Anzahl von Spalten, die Sie speichern intern und dann, wenn gefragt wird, die Daten für (Spalte, Zeile) bereitgestellt, damit die leeren Spalt überspringen.

Andere Tipps

Unter Mac OS X v10.5 und später gibt es die setHidden: Selektor NSTableColumn

Auf diese Weise können Spalten mit der Verwendung von Identifikatoren dynamisch versteckt / angezeigt werden:

NSInteger colIdx;
NSTableColumn* col;

colIdx = [myTable columnWithIdentifier:@"columnIdent"];
col = [myTable.tableColumns objectAtIndex:colIdx];
[col setHidden:YES];

Ich habe dies mit Bindungen getan, aber sie programmatisch statt durch Interface Builder zu setzen.

Dieses psuedo-Schnipsel sollten Sie den Kern von ihm geben:

NSTableColumn *aColumn = [[NSTableColumn alloc] initWithIdentifier:attr];
[aColumn setWidth:DEFAULTCOLWIDTH];
[aColumn setMinWidth:MINCOLWIDTH];
[[aColumn headerCell] setStringValue:columnLabel];

[aColumn bind:@"value"
     toObject:arrayController 
  withKeyPath:keyPath 
  options:nil];             

[tableView addTableColumn:aColumn];
[aColumn release];

Natürlich kann man hinzufügen, Formatierer und all das Zeug auch.

Es funktioniert nicht im Interface Builder. Allerdings funktioniert es programmatisch. Hier ist, wie ich einen NSTableViewColumn mit der Kennung „Status“ band an einen Schlüssel in meiner NSUserDefaults:

Swift:

tableView.tableColumnWithIdentifier("Status")?.bind("hidden", toObject: NSUserDefaults.standardUserDefaults(), withKeyPath: "TableColumnStatus", options: nil)

Objective-C:

[[self.tableView tableColumnWithIdentifier:@"Status"] bind:@"hidden" toObject:[NSUserDefaults standardUserDefaults] withKeyPath:@"TableColumnStatus" options:nil];

Ich habe keine vollständige Antwort zu dieser Zeit, aber in Bindungen suchen. Es ist grundsätzlich möglich, alle möglichen Dinge mit Cocoa Bindungen zu tun.

Es gibt keine Sichtbarkeit für NSTableColumn Bindung, aber Sie können die Breite auf 0 setzen können.

Dann können Sie es in den Null-Platzhalter binden und diesen Wert auf 0 - aber vergessen Sie nicht die anderen Platzhalter auf vernünftige Werte zu setzen

.

(Wie gesagt, das ist nur ein Anfang, es könnte einige Optimierungen benötigen).

Es gibt keine Zeit, um alle Daten gefüllt wird. NSTableView keine Daten speichern, fragt er dynamisch aus seiner Datenquelle (oder gebunden zu Objekten, wenn Sie Bindungen verwenden). Es zieht nur Daten unter Verwendung von aus der Datenquelle und Gräben wird es. Sie sollen nicht die Tabelle für die Daten für irgendetwas sehen fragen, die nicht sichtbar ist, zum Beispiel.

Es klingt wie Sie eine Datenquelle verwenden? Wenn sich die Daten ändern, ist es in Ihrer Verantwortung, auf den Tisch zu nennen -reloadData, die ein wenig irreführend ist. Es ist eher wie ‚ungültig machen alles‘.

Das heißt, man sollte schon wissen, wann die Datenänderungen. Das ist der Punkt, an dem Sie berechnen können, welche Spalten ausgeblendet werden sollen.

@amrox - Wenn ich Ihren Vorschlag richtig bin zu verstehen, Sie sagen, dass ich einen Wert in der verborgenen Eigenschaft des NSTableColumns in meinem Tisch binden sollte? Das scheint, wie es funktionieren würde, aber ich glaube nicht, dass NSTableColumn eine versteckte Eigenschaft hat, da die isHidden und setHidden Nachrichten, die die Sichtbarkeit der Spalte steuern - die mir sagt, dass dies nicht eine Eigenschaft, es sei denn ich etwas fehlte (was durchaus möglich ist).

Ich mag meine Lösung für Swift 4 unter Verwendung von Cocoa Bindungen und die tatsächliche isHidden Flagge aktualisiert schreiben, ohne die Spaltenbreiten berühren (wie Sie den ursprünglichen Wert danach wiederherstellen müssen möglicherweise ...). Angenommen, wir haben eine Checkbox eine Spalte Sichtbarkeit zu wechseln (oder Sie können immer wechseln die hideColumnsFlag Variable im Beispiel unten in irgendeiner anderen Art und Weise Sie mögen):

class ViewController: NSViewController {

     // define the boolean binding variable to hide the columns and use its name as keypath
     @objc dynamic var hideColumnsFlag = true

     // Referring the column(s)
     // Method 1: creating IBOutlet(s) for the column(s): just ctrl-drag each column here to add it
     @IBOutlet weak var hideableTableColumn: NSTableColumn!
     // add as many column outlets as you need...

     // or, if you prefer working with columns' string keypaths
     // Method 2: use just the table view IBOutlet and its column identifiers (you **must** anyway set the latter identifiers manually via IB for each column)
     @IBOutlet weak var theTableView: NSTableView! // this line could be actually removed if using the first method on this example, but in a real case, you will probably need it anyway.

     // MARK: View Controller Lifecycle

     override func viewDidLoad() {
         super.viewDidLoad()

         // Method 1
         // referring the columns by using the outlets as such:
         hideableTableColumn.bind(.hidden, to: self, withKeyPath: "hideColumnsFlag", options: nil)
         // repeat for each column outlet.

         // Method 2
         // or if you need/prefer to use the column identifiers strings then:
         // theTableView.tableColumn(withIdentifier: .init("columnName"))?.bind(.hidden, to: self, withKeyPath: "hideColumnsFlag", options: nil)
         // repeat for each column identifier you have set.

         // obviously use just one method by commenting/uncommenting one or the other.
     }

     // MARK: Actions

     // this is the checkBox action method, just toggling the boolean variable bound to the columns in the viewDidLoad method.
     @IBAction func hideColumnsCheckboxAction(_ sender: NSButton) {
         hideColumnsFlag = sender.state == .on
     }
}

Wie Sie vielleicht bemerkt haben, gibt es keine Möglichkeit noch ist die Hidden Flagge im Interface Builder als auf XCode10 zu binden: Sie Enabled oder Editable Bindungen sehen können, aber nur programmatisch erhalten Sie Zugriff auf die isHidden Flag für die Spalte, wie es in Swift genannt wird.

Wie in den Kommentaren erwähnt, stützt sich das zweite Verfahren auf die Spaltenkennungen Sie manuell entweder über Interface Builder auf dem Identity-Feld festlegen müssen die relevanten Spalten nach der Auswahl oder, wenn Sie ein Array von Spaltennamen haben, können Sie die Tabellenspalten aufzählen und weisen Sie die Kennungen sowie die Bindungen anstelle von ähnlichen Codezeilen zu wiederholen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top