Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

medasmx

macrumors member
Original poster
Nov 9, 2008
89
0
I have a skeleton program for custom cells in a table view. I took some ideas from a program online "customtableview" that I downloaded. One complaint that I have about it is that it does not draw a custom image; instead using a .tiff file.

Apple has a program called "dropNdragoutlineview". That program is pretty complicated, although on a post someone said it was bare-bones what was needed. My program has two classes, MyCell, the custom cell, and AppController, that contains the tableview. Below is the custom cell -

Code:
@implementation MyCell

-(void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView
{
	NSImage*myImage=[[NSImage alloc]init];
	[myImage lockFocus];
	myPath=[NSBezierPath bezierPathWithRect:cellFrame];
	NSColor*myColor=[NSColor blueColor];
	[myColor set];
	[myPath fill];
	[myImage unlockFocus];
	[myImage drawInRect:cellFrame fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
}

@end

One thing I would like to understand is how to make a custom cell with drawing. On apple's site they recommend using lockFocus and unlockFocus.

Next is the tableview --

Code:
@implementation AppController

-(id)init
{
	[super init];
	myArray=[NSArray arrayWithObjects:@"red",@"green",@"blue",@"purple"];
	[tableView setDelegate:self];
	return self;
}
-(IBAction)asmbutton1:(NSButton*)sender;
{
//some code to reset colors from myArray (in popupbutton), for cells in tableview
	[tableView reloadData];
}

-(int)numberOfRowsInTableView:(NSTableView *)tv
{
	return 2;
}

-(id)tableView:(NSTableView *)tv objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row 
{
	return myCell;
} 

@end

I'm sure it's much more complicated that this. Any suggestions would be helpful.

Adam
 
The main cell drawing method is
Code:
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
I wouldn't use any other unless you really know that you need them. You can just override this one to do your drawing.

I often start off with a basic rectangle to make sure my drawing rects are setup properly. For example:
Code:
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
    [[NSColor redColor] set];
    NSRectFill(NSInsetRect(cellFrame, 4.0, 4.0));
}
That will draw a red rectangle in the cell with a border.

There are multiple ways to setup a cell with a table column. The easiest is to do it in IB but that is a bit hard to explain. For now you can do this: setup an IBOutlet to your NSTableView, give your column an identifier in IB, and then create your cell like so:
Code:
- (void)awakeFromNib {
    MyCell *cell = [[[MyCell alloc] init] autorelease];
    NSTableColumn *column = [tableView tableColumnWithIdentifier:@"SomeIdentifier"];
    [column setDataCell:cell];

tableView:eek:bjectValueForTableColumn:row: should return data that the cell can use. Usually you're using NSTextFieldCell and NSImageCell, and so for those you could return NSStrings and NSImages but for your cell you'll want to return whatever the cell needs to draw. For example you could return an NSColor object, and then inside the NSCell you can call [self objectValue] to get that color.
 
I incorporated the suggestions from Kainjow, for which, thank you, Kainjow. Unfortunately can't get it to work. What I did was to set the column title in the interface builder, then called the identifier by the same name, "columnOne". Below is the code from the appcontroller.

Code:
-(void)awakeFromNib
{
	myCell=[[[MyCell alloc]init]autorelease];
	NSTableColumn*column=[tv tableColumnWithIdentifier:@"columnOne"];
	[column setDataCell:myCell];
}


-(id)init
{
	[super init];
	[tv setDelegate:self];
	return self;
}

-(int)numberOfRowsInTableView:(NSTableView *)tv
{
	return 1;
}

-(id)tableView:(NSTableView *)tv objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row 
{
	firstRow=[tableColumn dataCellForRow:1];
	return firstRow;
}

I changed myCell to the simple version, as seen in Kainjow's post. It has no errors, but then gets locked in the debugger. When stopped, you get the message "uncaught exception...unrecognized selector...[MyCell setControlView:]"

Again, thanks for any help.

Adam
 
the objectValueForTableColumn doesn't return cells. When you setDataCell, you're basically setting a prototype which gets reused over and over again for each row. The objectValueForTableColumn method returns data used by the cell. For this cell right now it doesn't use anything, so you could just return dummy data, but not a cell.

Edit: you can get rid of your init method above. Your table view won't be created by then, so it's not doing anything (and the delegate and datasource are usually set in IB anyways, which it sounds like you have setup already).

Edit2: here's an example controller that gives you dummy data you can use. If you remove the custom cell part then it'll just show as text since IB defaults to using NSTextFieldCell.

Code:
- (void)awakeFromNib
{
    data = [[NSArray alloc] initWithObjects:@"1", @"2", @"3", nil];

    MyCell *cell = [[[MyCell alloc] init] autorelease];
    NSTableColumn *tc = [tableView tableColumnWithIdentifier:@"MyColumn"];
    [tc setDataCell:cell];
}

- (int)numberOfRowsInTableView:(NSTableView *)tv
{
    return [data count];
}

- (id)tableView:(NSTableView *)tv objectValueForTableColumn:(NSTableColumn *)tc row:(NSInteger)row
{
    return [data objectAtIndex:row];
}
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.