Horizontale Linie in OutlineView

  • RE: Horizontale Linie in OutlineView

    Quellcode

    1. - (void)drawRow:(int)rowIndex clipRect:(NSRect)clipRect {
    2. [super drawRow:rowIndex clipRect:clipRect];
    3. NSDictionary* info = [self infoForBinding:@"content"];
    4. id item = [[[info objectForKey:NSObservedObjectKey] valueForKey:[info objectForKey:NSObservedKeyPathKey]] objectAtIndex:rowIndex];
    5. NSNumber* itemIndex = [item valueForKeyPath:@"posting.index"];
    6. NSNumber* limitItemIndex = [item valueForKeyPath:@"cluster.lastItem.posting.index"];
    7. if( [itemIndex isEqualToNumber:limitItemIndex] && rowIndex ) {
    8. [NSGraphicsContext saveGraphicsState];
    9. [[NSGraphicsContext currentContext] setShouldAntialias:NO];
    10. NSRect rowRect = [self rectOfRow:rowIndex];
    11. [[NSColor redColor] set];
    12. [NSBezierPath strokeLineFromPoint:NSMakePoint(NSMinX(rowRect),NSMinY(rowRect)+1)
    13. toPoint:NSMakePoint(NSMaxX(rowRect),NSMinY(rowRect)+1)];
    14. [NSGraphicsContext restoreGraphicsState];
    15. }
    16. }
    Alles anzeigen
    Ist jetzt zwar sehr speziell für meine Anwendung, aber als Wichsvorlage dürfte es reichen.
    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"?
  • Hi,
    mein Problem ist gerade, dass ich nicht über Bindings auf den Inhalt zugreifen kann. Der Inhalt wird über die dataSource und die entsprechenden Methoden geladen (-outlineView:child:ofItem:, -outlineView:isItemExpandable:, etc.pp.). Wie komme ich denn jetzt innerhalb der -drawRow, was ja eine Methode der gesubclassten NSOutlineView sein dürfte, an die Daten? Ich kann aber andererseits nicht einfach in das dataSource-Objekt eine beliebige Methode reinhauen...

    Chris
  • Ich kann aber andererseits nicht einfach in das dataSource-Objekt eine beliebige Methode reinhauen...

    Wieso nicht?

    Wenn du über Data-Sources gehst, ist exakt dies der vorgesehene Weg. Du gesht dabei am besten wie folgt vor:

    1. Protokoll definieren

    Quellcode

    1. @protocol DividedOutlineView
    2. - (BOOL)-outlineView:(NSOutlineView*)hasItemDividerAbove:(id)item;
    3. // oder etwa, wenn der divider eine eigene Zeile sein soll
    4. - (BOOL)-outlineView:(NSOutlineView*)isItemDivider(id)item;
    5. @end


    2. Methode in der Data-Suorce implementieren

    3. Methode statt des Bindings in dem if aufrufen.

    Ob du nun daraus eine eigene Zeile machst odr das als Attribut einer Zeile implementierst, ist deine Sache.
    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"?
  • Hi Tom,
    danke, das sieht gut aus.

    Allerdings stellt sich mir gerade noch eine kleine Frage: ich bekomme von -drawRow: nur den Index der Zeile, nicht aber das repräsentierte Element, das ja in deinem Protokollbeispiel übergeben wird. Wie komme ich innerhalb der Klasse nun zu dem entsprechenden Objekt?

    Ich stehe gerade wohl irgendwie auf dem Schlauch... :?

    Chris
  • Bei mir ging es um ein Table-View, kein Outline-View. Deshalb gab es das Problem nicht wirklich. Aber eigentlich müsste es dir doch dein Delegate liefern können. Ich gehe doch recht in der Annahme, dass die Striche nur auf oberster Ebene vorhanden sind?
    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"?
  • Ich stand echt auf'm Schlauch: -outlineView:child:ofItem: kann mir das geben. Es gibt, wenn ich das richtig sehe, im Wesentlichen nur ein Root-Objekte, und somit kann ich ofItem bedenkenlos nil übergeben. Scheint so zumindest so gedacht zu sein. ;)

    Danke für deine Hilfe,
    Chris
  • Hi,
    hab da doch noch eine Frage zu: wenn nun die entsprechenden Methoden doch nicht implementiert wurden, soll einfach angenommen werden, dass sie "false" geben würden und das Programm dennoch weiter machen. Stattdessen bekomme ich im Moment aber im RunLog lustige Meldungen um die Ohren gehauen:
    2007-04-18 13:45:52.617 xxxx[1955] *** -[xxxWindowController outlineView:isItemDivider:]: selector not recognized [self = 0xfd53360]

    Ich hab das Ganze nämlich noch ein wenig erweitert:

    Quellcode

    1. @interface NSObject (CHOutlineView_ItemDivider)
    2. - (BOOL)outlineView:(NSOutlineView*)outlineView hasItemDividerBelow:(id)item;
    3. - (BOOL)outlineView:(NSOutlineView*)outlineView isItemDivider:(id)item;
    4. - (BOOL)outlineView:(NSOutlineView*)outlineView hasItemDividerAbove:(id)item;
    5. @end

    Und davon ist eben nur eine Methode implementiert (brauche eben im Moment nur eine). Gibt es da eine Möglichkeit trotzdem diese Aufrufe durchzuführen, aber weiterzumachen, wenn sie in's Leere laufen?

    Chris
  • Ich könte jetzt auf

    Rodewig/Negm-Awad, Objective-C und Cocoa, S. 280 ff. verweisen. :)

    Dort wird nämlich ein optonales informelles Protokoll implementiert. Ich lass das aber und verweise auf -respondsToSelector:.

    Also: Du fragst alle drei Möglichkeiten ab. Wenn du keine findest, würde ich keine Exception schmeißen, sondern einfach NO (Was ist false?) annehmen.
    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"?
  • Quellcode

    1. - (BOOL)conformsToProtocol:(Protocol *)aProtocol
    ginge auch.
    Mein Punkt ist aber: NSOutLineView bildet mit 2 anderen Objekten, 'delegate' und 'datasource' schon einen satten Dreiklang, dann gibt es noch 'Cells' und 'binding', in anderen Worten, Platz genug für eine Implementierung.
    Mit Deiner Erweiterung in NSObject wird ein Grundprinzip verletzt: Kapselung. Jetzt kann ein WebView, ein FileManager und alle anderen Objekte auf Deine Methode antworten. Weil Du das aber dann doch nicht möchtest, musst Du jedesmal fragen.
    W.
    I would be embarrassed if they did not spy on me.
  • Neee, conformsToProtocol geht nicht, da du dann ein halb-formales Protokoll implementierst. Es müssen dann alle Methode implementiert werden, was unbequem bis sinnfrei ist. Wieso sollte ein Divier-Item einen Divider ober- oder unterhalb haben?
    +++
    [Falsch verstanden]

    Er hat es als Kategorie programmiert, nicht as Protokoll -- warum auch immer.

    Also weg mit der Kategorie und her mit dem Protokoll!
    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"?
  • Hi,
    äh, was jetzt? Angenommen ich hätte das Protokoll und würde conformsToProtocol: verwenden. Dann müsste ich doch wirklich alle Methoden implementieren... So gesehen hast du doch schon Recht, oder nicht? *kopfkratz*

    Dass es als Kategorie und nicht als Protokoll implementiert ist, hat erstmal nur den Sinn, dass mir das so empfohlen wurde. Warum weiß ich nicht, hab es erstmal nur blind übernommen. ;)

    Chris