Sto utilizzando l'opzione "Righe alternate" in Interface Builder per ottenere colori di righe alternati su un NSTableView. C'è un modo per cambiare i colori delle righe alternate?Cambia colori righe alternate NSTableView
risposta
Trovato un modo migliore per farlo here. Questo metodo sostituisce il metodo highlightSelectionInClipRect: in una sottoclasse NSTableView in modo da poter utilizzare qualsiasi colore desiderato per le righe alternate. Non è così maniacale come usare una categoria NSColor, e riguarda solo le visualizzazioni delle tabelle che scegli.
Non esiste alcuna proprietà impostabile per questo, tuttavia è possibile rispondere al metodo delegato -tableView:willDisplayCell:forTableColumn:row:
e impostare il colore di sfondo della cella in base all'uguaglianza del numero di riga.
Questo non sembra funzionare quando non ci sono celle della vista tabella (non cambia lo sfondo della vista tabella stessa) – indragie
Se si desidera utilizzare un modo non documentato, fare una categoria NSColor
e sovrascrivere _blueAlternatingRowColor
come questo:
@implementation NSColor (ColorChangingFun)
+(NSColor*)_blueAlternatingRowColor
{
return [NSColor redColor];
}
@end
o per modificare entrambi i colori, eseguire l'override controlAlternatingRowBackgroundColors
per restituire una matrice di colori che si desidera alternati.
@implementation NSColor (ColorChangingFun)
+(NSArray*)controlAlternatingRowBackgroundColors
{
return [NSArray arrayWithObjects:[NSColor redColor], [NSColor greenColor], nil];
}
@end
Perché mod quando l'API ti dà un modo? –
um, perché è divertente;) ROFL –
Funziona, ma cambia solo uno dei colori. – indragie
I sottoclasse NSTableView e attuate drawRow: clipRect: in questo modo ...
- (void)drawRow:(NSInteger)row clipRect:(NSRect)clipRect
{
NSColor *color = (row % 2) ? [NSColor redColor] : [NSColor whiteColor];
[color setFill];
NSRectFill([self rectOfRow:row]);
[super drawRow:row clipRect:clipRect];
}
Sembra funzionare, ma è così semplice che mi chiedo se mi manca qualcosa.
Sfortunatamente non fornisce colori alternati per righe vuote, solo righe che contengono dati. – Huperniketes
Questo ha funzionato bene per me. Potresti voler racchiudere le prime tre linee in un 'if (row! = [Self selectedRow])' per evitare problemi con lo sfondo evidenziato delle righe selezionate. – pepsi
@Huperniketes Controlla [questa domanda] (http://stackoverflow.com/questions/14178370/draw-nstableview-alternating-rows-like-itunes-11?rq=1) per una soluzione per disegnare anche lo sfondo della vista della tabella senza righe – Jay
volevo una soluzione che ha funzionato proprio come la normale NSTableView
, incluso il supporto per lo scorrimento elastico e simili, così ho creato un NSTableView
sottoclasse che ha un NSColor*
proprietà chiamata alternateBackgroundColor
, e quindi escludeva il metodo -drawBackgroundColorInClipRect:
in questo modo:
- (void) drawBackgroundInClipRect:(NSRect)clipRect {
if([self alternateBackgroundColor] == nil) {
// If we didn't set the alternate colour, fall back to the default behaviour
[super drawBackgroundInClipRect:clipRect];
} else {
// Fill in the background colour
[[self backgroundColor] set];
NSRectFill(clipRect);
// Check if we should be drawing alternating coloured rows
if([self alternateBackgroundColor] && [self usesAlternatingRowBackgroundColors]) {
// Set the alternating background colour
[[self alternateBackgroundColor] set];
// Go through all of the intersected rows and draw their rects
NSRect checkRect = [self bounds];
checkRect.origin.y = clipRect.origin.y;
checkRect.size.height = clipRect.size.height;
NSRange rowsToDraw = [self rowsInRect:checkRect];
NSUInteger curRow = rowsToDraw.location;
while(curRow < rowsToDraw.location + rowsToDraw.length) {
if(curRow % 2 != 0) {
// This is an alternate row
NSRect rowRect = [self rectOfRow:curRow];
rowRect.origin.x = clipRect.origin.x;
rowRect.size.width = clipRect.size.width;
NSRectFill(rowRect);
}
curRow++;
}
// Figure out the height of "off the table" rows
CGFloat rowHeight = [self rowHeight];
if(([self gridStyleMask] & NSTableViewSolidHorizontalGridLineMask) == NSTableViewSolidHorizontalGridLineMask
|| ([self gridStyleMask] & NSTableViewDashedHorizontalGridLineMask) == NSTableViewDashedHorizontalGridLineMask) {
rowHeight += 2.0f; // Compensate for a grid
}
// Draw fake rows below the table's last row
CGFloat virtualRowOrigin = 0.0f;
NSInteger virtualRowNumber = [self numberOfRows];
if([self numberOfRows] > 0) {
NSRect finalRect = [self rectOfRow:[self numberOfRows]-1];
virtualRowOrigin = finalRect.origin.y + finalRect.size.height;
}
while(virtualRowOrigin < clipRect.origin.y + clipRect.size.height) {
if(virtualRowNumber % 2 != 0) {
// This is an alternate row
NSRect virtualRowRect = NSMakeRect(clipRect.origin.x,virtualRowOrigin,clipRect.size.width,rowHeight);
NSRectFill(virtualRowRect);
}
virtualRowNumber++;
virtualRowOrigin += rowHeight;
}
// Draw fake rows above the table's first row
virtualRowOrigin = -1 * rowHeight;
virtualRowNumber = -1;
while(virtualRowOrigin + rowHeight > clipRect.origin.y) {
if(abs(virtualRowNumber) % 2 != 0) {
// This is an alternate row
NSRect virtualRowRect = NSMakeRect(clipRect.origin.x,virtualRowOrigin,clipRect.size.width,rowHeight);
NSRectFill(virtualRowRect);
}
virtualRowNumber--;
virtualRowOrigin -= rowHeight;
}
}
}
}
Per fare questo lavoro ho dovuto disabilitare usesAlternatingRowBackgroundColors e prendere il check out condizionale. Altrimenti, la vista della tabella stava disegnando sopra e ho visto solo le righe virtuali disegnate oltre i limiti della tabella. – greg
non sono sicuro di quanto recentemente è stato aggiunto questo, o se è flessibile come è necessario che sia, ma ho notato che è possibile specificare le righe "alternata" in Interface Builder in Xcode 4.6 (e forse anche prima) .
- Aprire il pennino in Xcode e selezionare il
NSTableView
oNSOutlineView
- mostrare gli attributi Ispettore nel riquadro Utilities (⎇⌘4)
- Avviso la casella di controllo
Highlight Alternating Rows
.
Sì, questa è l'opzione che stavo usando (è in circolazione da un po '). Il problema è stato riuscire a personalizzare i colori alternati da quando ticchetti quella casella ti dà solo i colori di sistema luce blu/bianco di default. – indragie
s' answerNate Thorn ha funzionato perfettamente per me.
Qui è, refactoring per Swift:
import Foundation
import Cocoa
import AppKit
public class SubclassedTableView : NSTableView {
private func
alternateBackgroundColor() -> NSColor? {
return NSColor.redColor() // Return any color you like
}
public override func
drawBackgroundInClipRect(clipRect: NSRect) {
if alternateBackgroundColor() == nil {
// If we didn't set the alternate colour, fall back to the default behaviour
super.drawBackgroundInClipRect(clipRect)
} else {
// Fill in the background colour
self.backgroundColor.set()
NSRectFill(clipRect)
// Check if we should be drawing alternating coloured rows
if usesAlternatingRowBackgroundColors {
// Set the alternating background colour
alternateBackgroundColor()!.set()
// Go through all of the intersected rows and draw their rects
var checkRect = bounds
checkRect.origin.y = clipRect.origin.y
checkRect.size.height = clipRect.size.height
let rowsToDraw = rowsInRect(checkRect)
var curRow = rowsToDraw.location
repeat {
if curRow % 2 != 0 {
// This is an alternate row
var rowRect = rectOfRow(curRow)
rowRect.origin.x = clipRect.origin.x
rowRect.size.width = clipRect.size.width
NSRectFill(rowRect)
}
curRow++
} while curRow < rowsToDraw.location + rowsToDraw.length
// Figure out the height of "off the table" rows
var thisRowHeight = rowHeight
if gridStyleMask.contains(NSTableViewGridLineStyle.SolidHorizontalGridLineMask)
|| gridStyleMask.contains(NSTableViewGridLineStyle.DashedHorizontalGridLineMask) {
thisRowHeight += 2.0 // Compensate for a grid
}
// Draw fake rows below the table's last row
var virtualRowOrigin = 0.0 as CGFloat
var virtualRowNumber = numberOfRows
if numberOfRows > 0 {
let finalRect = rectOfRow(numberOfRows-1)
virtualRowOrigin = finalRect.origin.y + finalRect.size.height
}
repeat {
if virtualRowNumber % 2 != 0 {
// This is an alternate row
let virtualRowRect = NSRect(x: clipRect.origin.x, y: virtualRowOrigin, width: clipRect.size.width, height: thisRowHeight)
NSRectFill(virtualRowRect)
}
virtualRowNumber++
virtualRowOrigin += thisRowHeight
} while virtualRowOrigin < clipRect.origin.y + clipRect.size.height
// Draw fake rows above the table's first row
virtualRowOrigin = -1 * thisRowHeight
virtualRowNumber = -1
repeat {
if abs(virtualRowNumber) % 2 != 0 {
// This is an alternate row
let virtualRowRect = NSRect(x: clipRect.origin.x, y: virtualRowOrigin, width: clipRect.size.width, height: thisRowHeight)
NSRectFill(virtualRowRect)
}
virtualRowNumber--
virtualRowOrigin -= thisRowHeight
} while virtualRowOrigin + thisRowHeight > clipRect.origin.y
}
}
}
}
+100 Ho incontrato questa domanda alcuni giorni fa sperando in una buona risposta, ma non ne trovai una soddisfacente. Per fortuna, mi è capitato di vederlo venire di nuovo! Grazie! –
Questo non ha funzionato abbastanza per me. Sembra buono a meno che non inizi a scorrere su e giù con la barra di scorrimento. Quindi il re-drawing viene incasinato e si finisce con un sacco di linee orizzontali bianche nelle righe colorate. Ho messo la mia implementazione qui sotto, ma è così semplice che mi chiedo se mi manchi qualcosa. – sam