Nochmal TableView füllen

  • Ich habe hier jetzt eines seit 10 Tagen liegen. Keine Zeit. Man kann da ja nicht mal so eben 10 Sekunden hereinschauen, wie in einen Forenbeitrag.

    BTW: Umso löblicher, dass du dir jetzt die Zeit für andere nimmst. Das ist leider viel zu selten der Fall.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Gut, ist ein fairer Vorschlag.

    Ich nehme mal das Beispielprojekt von Hillegass.
    Es ist ein TableView mit zwei Einträgen :Artikel und Preis.
    Dem Beispiel folgend habe ich 2 Buttons zum Einfügen und Löschen von Einträgen. Das funktioniert (ist ja auch nicht von mir).

    Was ich gerne hätte - wie beschrieben - ist, dass das Programm die beigefügte Textdatei beim Start einliest und das TableView mit diesen Einträgen gefüllt wird.
    Per Default soll der deutsche Namen des Artikels und durch Betätigen des Buttons "Deutsch-English" sollte der englische statt des deutschen Eintrags kommen.

    Hans

    Aufgrund der Grössenlimitierung von 49 kB musste ich 3 files erzeugen. Ich hoffe, es geht trotzdem.
  • Textdateien einlesen ist wieder eine andere Geschichte. Schau Dir dazu das mal an:
    macresearch.org/cocoa-scientists-part-xxvi-parsing-csv-data
    Kurz gesagt: Schau Dir NSString an: "Dividing String", dort "componentsSeparatedByString:"
    ganz kurz: Du lädst die Textdatei in einen String, zerlegst die Zeilen und danach die Spalten mit componentsSeparatedByString und schreibst das in Deine Personen.

    Beiliegendes Projekt-II funktioniert.

    No.
  • Wunderbar !

    das funktioniert ja genauso wie ich es haben wollte, vielen Dank !

    Ein paar kleine Detailfragen noch :

    1) Ich komme zurück auf den gestern unverstandenen Punkt 5 und deinem Quellcode :

    Die KVC-Kompatibilität des Array kann entweder erfolgen durch :

    Quellcode

    1. self.myPersonArray = tempArray
    oder

    Quellcode

    1. [self setValue:tempArray forKey:@"myPersonArray"]

    Diese Methoden sind gleichwertig, ist das richtig ?

    2) Wenn im TableView in der Kolumne "Name" der deutsche Name steht und ich durch Drücken eines Buttons auf englisch wechseln will :
    Muss ich die Datendatei neu einlesen und "aPerson.name" den englischen Wert zuweisen (was irgendwie umständlich wäre) oder kann ich den "Model Key Path"
    im Quellcode ändern, dass aus "name_german" "name_english" wird ?
    Schliesslich werden beide Namen beim Start eingelesen, nur wird eben lediglich der eine davon angezeigt ?

    Hans
  • 1)
    Guckst Du hier:
    developer.apple.com/documentat…c/uid/TP30001163-CH17-SW6

    2)
    Die Datendatei musst Du nicht neu einlesen. Du hast ja beide Namen, deutsch und englisch, in Deinen Personen gespeichert. Du mußt dem TableView nur mitteilen, etwas anderes anzuzeigen. Da gibt's sicher mehrere Möglichkeiten, über die ich noch nicht nachgedacht habe. Was aber sicher geht:
    - Du könntest für deutsch und englisch Spalten im TableView vorsehen und via Code die eine oder andere TableView-Spalte ausblenden.
    - Du könntest via Code das Spaltenbinding im TableView ändern.
    Gibt sicher noch andere Möglichkeiten.

    No.
  • 1) Identifizieren der NSTableColumn, am besten über einen Identifier, siehe IB
    Methode: "columnWithIdentifier:" von NSTableView
    2) altes Binding entfernen mit "unbind:", siehe doku
    3) neues Binding herstellen mit "bind:toObject:withKeyPath:options:"

    2+3 siehe NSKeyValueBindingCreation Protocol

    Ein Beispiel für 3):

    [rankineTemperatureField bind: @"value"
    toObject: sharedUserDefaultsController
    withKeyPath: @"values.LastTemperature"
    options: bindingOptions];


    Am besten machst das in Deinem Controller, dem Du ein Outlet zum NSTableView hinzufügst.

    Was gerade gebunden ist, findest Du mit "- (NSDictionary *)infoForBinding:(NSString *)binding" heraus.
    NSLog ist da Dein Freund. Gibt ja Dictionaries als Parameter sauber als Text aus. Beispiel: NSLog(@"BindingDictionary %@", myBindingCitionary); Da kannst Dir im Debugger schön ansehen, was drinsteht.

    No.
  • Vielleicht noch eine Zusatzfrage :

    Wenn das TableView so wie hier quasi über den NSArrayController befüllt wird und es sind mehr Einträge als Platz im TableView erscheinen automatisch die Scrollbalken.

    Verfahre ich aber so (ohne NSArrayController) :

    //in awakefromNib

    Quellcode

    1. Person *aPerson = [[[Person alloc] init]autorelease];
    2. Person1 *aPerson = [[[Person1 alloc] init]autorelease];
    3. Person2 *aPerson = [[[Person2 alloc] init]autorelease];
    4. ...
    5. Person10 *aPerson = [[[Person10 alloc] init]autorelease];
    6. personenArray = [[NSMutableArray alloc] init];
    7. [personenArray addObject:aPerson]
    8. .....
    9. [personenArray addObject:aPerson10]
    10. //Anzeige
    11. -(id)tableView:(NSTableView *)aTable
    12. objectValueForTableColumn: (NSTableColumn *)aTableColumn
    13. row:(int)row {
    14. return [[personenArray objectAtIndex:row] name];
    15. }
    16. -((int)numberOfRowsInTableView:(NSTableView *)aTable {
    17. return [personenArray count];
    18. }
    Alles anzeigen

    so sehe ich keine Scrollbalken, selbst wenn die Anazhl der Einträge dies erfordern würde. ?(


    Gebe ich aber manuell den Rückgabewert ein (ist natürlich Quatsch fürs Endprodukt) :

    Quellcode

    1. -((int)numberOfRowsInTableView:(NSTableView *)aTable {
    2. return 10;
    3. }
    wird der Scrollbalken sofort angezeigt.

    Ich nehme an, da fehlt eine Aktualisierung der Anzeige. Aber wie veranlase ich die ??

    Hans
  • der Table View fragt sein DELEGATE-Outlet danach:
    -(id)tableView:(NSTableView *)aTable
    objectValueForTableColumn: (NSTableColumn *)aTableColumn
    row:(int)row

    Ist kein Delegate gesetzt (= das Outlet nicht verbunden), kommt die Frage niemals an.

    Das brauchst aber nicht, wenn Du den ArrayController, also Bindings benutzt. Obiges ist die "alte" Delegate-Methode, Daten an das TableView zu liefern. Genau wie "numberOfRowsInTableView..."

    Kurzum: das alles brauchst Du nicht, wenn Du Bindings verwendest, was Du mit dem Arraycontroller ja tust.

    No.
  • @ No : das Delegate ist gesetzt, sonst würden ja keine Werte erscheinen.
    Ich sehe nur die letzten Werte nicht, da kein Scrollbalken erscheint.

    Das brauchst aber nicht, wenn Du den ArrayController, also Bindings benutzt. Obiges ist die "alte" Delegate-Methode, Daten an das TableView zu liefern. Genau wie "numberOfRowsInTableView..."

    -> ist mir Dank Deiner Erklärungen inzwischen klar. Ich habe mich nur durch diverse Beipiele für TableViews gelesen und bin auch auf diese Methode gestossen.
    Für Lernzwecke wars sehr gut, man bekommt ein etwas besseres Verständnis.

    @wolf_10de : ja, stimmt, so gehts. Ein reload nach dem Einlesen der Daten und die Scrollbalken erscheinen.

    Besten Dank
    Hans