2012-08-22 2 views
9

Ein view-based NSTableView mit Zeilen, die dynamische Höhen haben, ändert seine Zeilen nicht, wenn die Tabellenansichtsgröße geändert wird. Dies ist ein Problem, wenn die Zeilenhöhe von der Breite der Tabellenansicht abgeleitet wird (Denken Sie an Textblöcke, die eine Spalte füllen und umbrechen, wodurch die Zeilengröße erweitert wird).Zeilen in sichtbasiertem NSTableView richtig skalieren

Ich habe versucht, NSTableView zu bekommen ihre Zeilen, um die Größe, wenn es Größe geändert, aber haben wenig Erfolg erlebt:

  • Wenn ich durch die Abfrage enumerateAvailableRowViewsUsingBlock:, einige der nicht-sichtbaren Zeilen nur die sichtbaren Zeilen die Größe Die Größe wird nicht geändert und wurde daher mit der alten Höhe angezeigt, wenn der Benutzer scrollt und diese Zeilen aufdeckt.
  • Wenn ich die Größe aller Zeilen ändere, wird es merklich langsam, wenn es viele Zeilen gibt (etwa 1 Sekunde Verzögerung nach jedem Fenster für 1000 Zeilen in meinem 1.8Ghz i7 MacBook Air).

Jeder kann helfen? Diese

ist, wo ich die Tabellenansicht Größenänderung erkennen - in der Delegiertentabellenansicht:

- (void)tableViewColumnDidResize:(NSNotification *)aNotification 
{ 
    NSTableView* aTableView = aNotification.object; 
    if (aTableView == self.messagesView) { 
     // coalesce all column resize notifications into one -- calls messagesViewDidResize: below 

     NSNotification* repostNotification = [NSNotification notificationWithName:BSMessageViewDidResizeNotification object:self]; 
     [[NSNotificationQueue defaultQueue] enqueueNotification:repostNotification postingStyle:NSPostWhenIdle]; 
    } 
} 

Während der folgenden ist die Prozedur der Anmeldung oben geschrieben, wo die sichtbaren Zeilen verkleinert erhalten:

-(void)messagesViewDidResize:(NSNotification *)notification 
{ 
    NSTableView* messagesView = self.messagesView; 

    NSMutableIndexSet* visibleIndexes = [NSMutableIndexSet new]; 
    [messagesView enumerateAvailableRowViewsUsingBlock:^(NSTableRowView *rowView, NSInteger row) { 
     if (row >= 0) { 
      [visibleIndexes addIndex:row]; 
     } 
    }]; 
    [messagesView noteHeightOfRowsWithIndexesChanged:visibleIndexes]; 
} 

Die alternative Implementierung, die alle Zeilen ändert die Größe sieht wie folgt aus:

-(void)messagesViewDidResize:(NSNotification *)notification 
{ 
    NSTableView* messagesView = self.messagesView;  
    NSIndexSet indexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0,messagesView.numberOfRows)];  
    [messagesView noteHeightOfRowsWithIndexesChanged:indexes]; 
} 

Hinweis: Diese Frage hängt etwas mit View-based NSTableView with rows that have dynamic heights zusammen, ist jedoch stärker darauf ausgerichtet, auf die Größenänderung der Tabellenansicht zu reagieren.

Antwort

11

Ich ging gerade durch genau dieses Problem. Was ich tat, war die NSViewBoundsDidChangeNotification für den Inhalt anzeigen

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(scrollViewContentBoundsDidChange:) name:NSViewBoundsDidChangeNotification object:self.scrollView.contentView]; 

und im Handler, erhalten die sichtbaren Zeilen und rufen noteHeightOfRowsWithIndexesChange die Scroll-Ansicht überwachen :. Ich deaktivieren Animation während dies zu tun, damit der Benutzer nicht sieht, die Zeilen während der Resize wackeln wie nach Ansicht des kommt in die Tabelle

- (void)scrollViewContentBoundsDidChange:(NSNotification*)notification 
{ 
    NSRange visibleRows = [self.tableView rowsInRect:self.scrollView.contentView.bounds]; 
    [NSAnimationContext beginGrouping]; 
    [[NSAnimationContext currentContext] setDuration:0]; 
    [self.tableView noteHeightOfRowsWithIndexesChanged:[NSIndexSet indexSetWithIndexesInRange:visibleRows]]; 
    [NSAnimationContext endGrouping]; 
} 

Diese schnell scrollt, so dass die Tabelle schön zu erfüllen hat, aber seine Arbeit sehr gut für mich.

+0

Für mich habe ich gewartet, bis der Benutzer die Größenänderung abgeschlossen haben, dann die Zeilenhöhen neu einstellen. – adib

+1

Offensichtlich veröffentlicht die Inhaltsansicht der Änderungsansicht keine Änderungsbenachrichtigungen, selbst nach dem Aufruf von '[self.scrollView.contentView setPostsBoundsChangedNotifications: YES]' – adib

+1

es scheint, dass NSViewFrameDidChangNotification besser für Live-Größenanpassung –