NSTableView Spaltenbreite nach längstem String berechnen

  • NSTableView Spaltenbreite nach längstem String berechnen

    Hallo,

    ich such mir schon wieder nen Wolf um die Spalten einer Tabelle auf den längsten String auszurichten. Irgendwie hab ich einfach kein passendes Beispiel gefunden. Sollte das nicht über Bindings recht einfach funktionieren, es gibt doch speziell ein "width" Attribut? Ich habe schon probiert einen Valuetransformer zu schreiben, aber selbst da stecke ich gerade fest. Der width Parameter nöchte gerne einen float haben, aber soweit ich weiß kann man nur ganze Objekte zurück geben. Also NSNumber....mhhhh

    Ich hab an sowas in der Art gedacht:

    Quellcode

    1. @implementation ColumnWidthValueTransformer
    2. + (Class)transformedValueClass { return [NSNumber class]; }
    3. + (BOOL)allowsReverseTransformation { return YES; }
    4. - (id)transformedValue:(id)value
    5. {
    6. if([value isKindOfClass:[NSArray class]])
    7. {
    8. //Pseudocode
    9. //suche den längsten String im Array
    10. //berechne die breite
    11. return [NSNumber numberWithFloat:breite];
    12. }
    13. return 100.0;
    14. }
    Alles anzeigen


    Bin ich da komplett auf dem Holzweg? Finde einfach nix zum Code spicken. Wenn jemand nen schlauen Link für mich parat hat, dann wäre mir sehr geholfen.
  • na sagen wir mal da steht bei return:

    Quellcode

    1. return [NSNumber numberWithFloat:50.0];

    Sorry, das war noch ein Überbleibsel von einmal zu wenig auf Undo geklickt.

    Ich habe diesen ValueTransformer unter "with" an einen NSTableColumn gebunden.

    Jedenfalls, wird die Spalte beim öffnen der Applikation durch meinen Transformer beeinflusst. Verändere ich oben am Tabellenkopf manuell die weite, dann werden meine ganzen Strings, durch 100 ersetzt....hmmmm, komisch. So wollte ich das ja nun nicht.
  • Bist du dir sicher, dass du die Spaltenbreite abhängig vom Inhalt der jeweiligen Spalte und der Zeilen machen möchtest? Das wird nämlich recht rechenintensiv. Für jede Zeile musst du unter Berücksichtigung der Einstellungen deren Breite bestimmen. Das ist erstmal ein O(n)-Problem. Wil Shipley sagt: Hast du ein O(n)-Problem und ist n<1000 - scheiss drauf. Ist n>1000 - fixe das Problem. Was ich damit sagen will: Dein Vorhaben ist fehleranfällig, kompliziert, rechenintensiv und scheint auf den ersten Blick nicht viel zu bringen.
    Die Objective-Cloud ist fertig wenn sie fertig ist. Beta heißt Beta.

    Objective-C und Cocoa Band 2: Fortgeschrittene
    Cocoa/Objective-C Seminare von [co coa:ding].
  • Also die Daten, welche in meiner Tabelle abgebildet werden sollen, übersteigen bei weitem nicht die 1000 Einträge. Lass es vielleicht 100 sein. Es muß auch nicht zwingend über die Bindings gelöst werden, ich dachte nur, dass man den Transformer wiederverwenden kann. Es gibt ja auch feste Spalten mit Nummern, da kann ich die Spaltenbreite fix lassen. Nur an den Stellen wo's gebraucht ist, würde ich den ValueTransformer benutzen.

    Mich wurmt es eben immer, wenn ich erst die Tabellen zurecht zupfen muss, damit ich den Inhalt auf einen einen Blick erfassen kann.

    Ich werde mal eine Beispielszene bauen. Hier ist eine Beispielszene den ValueTransformer habe ich auf die Spalte mit "Inhalt 2" gesetzt.
  • Original von wrongspot
    Ich hab hier im Forum gesucht, aber mit meiner Suchkombination nicht den entsprechenden Beitrag gefunden. Wenn der gnädige Herr mir einen Hinweis geben könnte, wo ich nachschauen muss :rolleyes: wäre mir sehr geholfen.


    kann dir leider net helfen - die suchfunktion funktioniert wirklich net richtig.

    vielleicht meldet sich ja derjenige zu wort der es gepostet hat.
  • Ok, das berechnen der Stringbreite war eher weniger das Problem, sondern der ValueTransformer. Aber nach ein wenig überlegen erscheint das Problem logisch. Die Spaltenbreite (width) wird per Code ausgerichtet, verschiebe ich den Header der Tabelle manuell mit der Maus, dann müsste man für diesen Augenblick das Binding auflösen.

    So hab ich es in der Art gelöst, das ich das "User Resizable" unterbunden habe. Die Korrekte Länge wird ja sowieso eingestellt. Aber danke für den Codeschnippsel auf der Seite von gritsch's Empfehlung.

    Hier noch der Code für meinen ValueTransformer:


    Quellcode

    1. @interface ColumnWidthValueTransformer : NSValueTransformer
    2. {
    3. NSDictionary *attributes;
    4. }
    5. @end
    6. @implementation ColumnWidthValueTransformer
    7. + (Class)transformedValueClass { return [NSNumber class]; }
    8. - (id) init
    9. {
    10. if ([super init] != nil)
    11. {
    12. attributes = [[NSDictionary dictionaryWithObjectsAndKeys:
    13. [NSFont fontWithName:@"Lucida Grande" size:12] , NSFontAttributeName,
    14. nil ] retain];
    15. }
    16. return self;
    17. }
    18. - (id)transformedValue:(id)value
    19. {
    20. float maxWidth = 0;
    21. if([value isKindOfClass:[NSArray class]])
    22. {
    23. if([value count] > 0 )
    24. {
    25. for(id Item in value)
    26. {
    27. if(![Item isKindOfClass:[NSNull class]])
    28. {
    29. float lineWidth = [Item sizeWithAttributes:attributes].width;
    30. maxWidth = MAX(maxWidth, lineWidth);
    31. }
    32. }
    33. if( maxWidth > 80.0)
    34. return [NSNumber numberWithFloat:maxWidth + 20.0];
    35. }
    36. }
    37. return [NSNumber numberWithFloat:80.0];
    38. }
    39. - (void) dealloc
    40. {
    41. [attributes release];
    42. [super dealloc];
    43. }
    44. @end
    Alles anzeigen


    funktioniert zumindest für alle Stringwerte.
  • den Stöpsele ich an den with Parameter vom TableColumn. Ich nutze einfach die ArrangedObjets und filtere mit dem ValueTransformer die größte Spalte raus. Das schön dran, man kann es öftter verwenden und genau in den Spalten wo man es braucht.