Skip to content

Instantly share code, notes, and snippets.

@CodaFi
Last active December 16, 2016 07:29
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CodaFi/4470973 to your computer and use it in GitHub Desktop.
Save CodaFi/4470973 to your computer and use it in GitHub Desktop.
Used in conjunction with a Cell-Based NSTableView to draw an iTunes-11 Style table view rows, along with fake rows on the top and bottom of the Table View. The clip view mentioned in the implementation does no actual drawing, and can be eliminated in favor of another arbitrary clip view or removed entirely. This gist uses the clip view swapping …
//
// CFIAlternatingTableView.m
//
// Created by Robert Widmann on 1/6/13.
// Copyright (c) 2015 CodaFi. All rights reserved.
//
#import "CFIAlternatingTableView.h"
#import "CFIAlternatingClipView.h"
@interface CFIAlternatingTableView ()
@property (nonatomic, strong) NSArray *colors;
@end
@implementation CFIAlternatingTableView
- (id)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
[self swapClipViewInScrollView:self.enclosingScrollView];
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
[self swapClipViewInScrollView:self.enclosingScrollView];
return self;
}
- (void)swapClipViewInScrollView:(NSScrollView *)scrollView {
self.colors = @[[NSColor colorWithCalibratedRed:0.932 green:0.946 blue:0.960 alpha:1.000], [NSColor colorWithCalibratedWhite:0.975 alpha:1.000]];
id documentView = [scrollView documentView];
CFIAlternatingClipView *clipView = [[CFIAlternatingClipView alloc] initWithFrame:[[scrollView contentView] frame]];
scrollView.contentView = clipView;
scrollView.documentView = documentView;
}
// Drawing code modified from http://stackoverflow.com/a/5101923/945847 to look
// like iTunes's alternating rows.
- (void)drawRow:(NSInteger)row clipRect:(NSRect)clipRect {
NSRect cellBounds = [self rectOfRow:row];
NSColor *color = (row % 2) ? [NSColor colorWithCalibratedWhite:0.975 alpha:1.000] : [NSColor colorWithCalibratedRed:0.932 green:0.946 blue:0.960 alpha:1.000];
[color setFill];
NSRectFill(cellBounds);
// Slightly dark gray color
[[NSColor colorWithCalibratedWhite:0.912 alpha:1.000] set];
// Get the current graphics context
CGContextRef currentContext = [NSGraphicsContext.currentContext graphicsPort];
//Draw a one pixel line of the slightly lighter blue color
CGContextSetLineWidth(currentContext, 1.0f);
// Start the line at the top of our cell
CGContextMoveToPoint(currentContext, 0.0f, NSMaxY(cellBounds));
// End the line at the edge of our tableview, for multi-columns, this will actually be overkill
CGContextAddLineToPoint(currentContext, NSMaxX(cellBounds), NSMaxY(cellBounds));
// Use the context's current color to draw the line
CGContextStrokePath(currentContext);
// Slightly lighter blue color
[[NSColor colorWithCalibratedRed:0.961 green:0.970 blue:0.985 alpha:1.000] set];
CGContextSetLineWidth(currentContext, 1.0f);
CGContextMoveToPoint(currentContext, 0.0f, 0.0f);
CGContextAddLineToPoint(currentContext, NSMaxX(self.bounds), 0.0f);
CGContextStrokePath(currentContext);
[super drawRow:row clipRect:clipRect];
}
-(void)drawBackgroundInClipRect:(NSRect)clipRect {
// The super class implementation obviously does something more than just
// drawing the striped background, because if you leave this out it looks
// funny
[super drawBackgroundInClipRect:clipRect];
CGFloat yStart = 0;
NSInteger rowIndex = -1;
if (clipRect.origin.y < 0) {
while (yStart > NSMinY(clipRect)) {
CGFloat yRowTop = yStart - self.rowHeight;
NSRect rowFrame = NSMakeRect(0, yRowTop, clipRect.size.width, self.rowHeight);
NSUInteger colorIndex = rowIndex % self.colors.count;
NSColor *color = [self.colors objectAtIndex:colorIndex];
[color set];
NSRectFill(rowFrame);
// Slightly dark gray color
[[NSColor colorWithCalibratedWhite:0.912 alpha:1.000] set];
// Get the current graphics context
CGContextRef currentContext = [[NSGraphicsContext currentContext]graphicsPort];
//Draw a one pixel line of the slightly lighter blue color
CGContextSetLineWidth(currentContext, 1.0f);
// Start the line at the top of our cell
CGContextMoveToPoint(currentContext, 0.0f, yRowTop + self.rowHeight - 1);
// End the line at the edge of our tableview, for multi-columns, this will actually be overkill
CGContextAddLineToPoint(currentContext, NSMaxX(clipRect), yRowTop + self.rowHeight - 1);
// Use the context's current color to draw the line
CGContextStrokePath(currentContext);
// Slightly lighter blue color
[[NSColor colorWithCalibratedRed:0.961 green:0.970 blue:0.985 alpha:1.000] set];
CGContextSetLineWidth(currentContext, 1.0f);
CGContextMoveToPoint(currentContext, 0.0f, yRowTop);
CGContextAddLineToPoint(currentContext, NSMaxX(clipRect), yRowTop);
CGContextStrokePath(currentContext);
yStart -= self.rowHeight;
rowIndex--;
}
}
}
-(void)drawGridInClipRect:(NSRect)clipRect {
[super drawGridInClipRect:clipRect];
NSUInteger numberOfRows = self.numberOfRows;
CGFloat yStart = 0;
if (numberOfRows > 0) {
yStart = NSMaxY([self rectOfRow:numberOfRows - 1]);
}
NSInteger rowIndex = numberOfRows + 1;
while (yStart < NSMaxY(clipRect)) {
CGFloat yRowTop = yStart - self.rowHeight;
NSRect rowFrame = NSMakeRect(0, yRowTop, clipRect.size.width, self.rowHeight);
NSUInteger colorIndex = rowIndex % self.colors.count;
NSColor *color = [self.colors objectAtIndex:colorIndex];
[color set];
NSRectFill(rowFrame);
// Slightly dark gray color
[[NSColor colorWithCalibratedWhite:0.912 alpha:1.000] set];
// Get the current graphics context
CGContextRef currentContext = [[NSGraphicsContext currentContext]graphicsPort];
//Draw a one pixel line of the slightly lighter blue color
CGContextSetLineWidth(currentContext, 1.0f);
// Start the line at the top of our cell
CGContextMoveToPoint(currentContext, 0.0f, yRowTop - self.rowHeight);
// End the line at the edge of our tableview, for multi-columns, this will actually be overkill
CGContextAddLineToPoint(currentContext, NSMaxX(clipRect), yRowTop - self.rowHeight);
// Use the context's current color to draw the line
CGContextStrokePath(currentContext);
// Slightly lighter blue color
[[NSColor colorWithCalibratedRed:0.961 green:0.970 blue:0.985 alpha:1.000] set];
CGContextSetLineWidth(currentContext, 1.0f);
CGContextMoveToPoint(currentContext, 0.0f, yRowTop);
CGContextAddLineToPoint(currentContext, NSMaxX(self.bounds), yRowTop);
CGContextStrokePath(currentContext);
yStart += self.rowHeight;
rowIndex++;
}
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment