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

elorc

macrumors newbie
Original poster
Apr 1, 2009
12
0
I have an NSTableView with four columns in a document-based Cocoa app. This tableview uses an NSMutableArray to hold its values. The four columns are:

1: User's name
2: Starting Balance
3: Deductions
4: Current Balance

What I want to happen is every time columns 2 or 3 are changed, I want the program to recalculate the value displayed in column 4.

I'm not really sure how this is done since I'm still a big newb with Objective C. :D Could someone provide some information or some sample code? Thanks!


* Update: Okay, I figured out how to make that last column editable so I removed that section of the question. I didn't realize it was as easy as selecting the column and unchecking the "Editable" box. :)
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
Are you using bindings, or a datasource? If bindings, you'll need to observe the array for changes to those fields. If using a datasource, you need to implement tableView:setObjectValue:forTableColumn:row:. With either one you need to get the selected object and calculate and update Current Balance based on the other values, then reload the table.
 

elorc

macrumors newbie
Original poster
Apr 1, 2009
12
0
Sorry it's been a while. :) ok so I'm making some progress here but I hit an issue I'm not quite sure I understand.

Code:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
	if ([keyPath isEqual:@"finalBalance"])
	{
		NSLog(@"No need to update for finalBalance.");
		return;
	}
	
	NSUndoManager *undo = [self undoManager];
	id oldValue = [change objectForKey:NSKeyValueChangeOldKey];
	
	if (oldValue == [NSNull null])
	{
		oldValue = nil;
	}
	
	if ([keyPath isEqual:@"usersName"])
	{
		NSLog(@"Don't update for usersName change");
	}
	else
	{
		// Update finalBalance
		int iStartValue = [object startingBalance];
		NSLog(@"The value of iStartValue is %d", iStartValue);
		
		int iAdjustment = [object deductionsFromBal];
		NSLog(@"The value of iAdjustment is %d", iAdjustment);
		
		int iNewValue = iStartValue - iAdjustment;
		NSLog(@"The value of iNewValue is %d", iNewValue);
		
		[object setValue:iNewValue forKeyPath:@"finalBalance"];
		NSLog(@"The finalBalance for %@ has been adjusted to %d", object, iNewValue);
	}
	
	[[undo prepareWithInvocationTarget:self] changeKeyPath:keyPath 
												  ofObject:object 
												   toValue:oldValue];
	
	[undo setActionName:@"Edit"];
}

At the line where I have [object setValue:iNewValue forKeyPath:mad:"finalBalance"];, I get this in the code:

warning: passing argument 1 of 'setValue:forKeyPath' makes pointer from integer without a cast

When I edit one of these columns in the program, it crashes to gdb. What am I doing wrong here?
 

eddietr

macrumors 6502a
Oct 29, 2006
807
0
Virginia
At the line where I have [object setValue:iNewValue forKeyPath:mad:"finalBalance"];, I get this in the code:

warning: passing argument 1 of 'setValue:forKeyPath' makes pointer from integer without a cast

When I edit one of these columns in the program, it crashes to gdb. What am I doing wrong here?

[NSObject setValue:forKeyPath] expects a pointer to an object. It can't take a scalar directly. So you have to wrap your int in an NSNumber like so:

Code:
[object setValue: [NSNumber numberWithInt:iNewValue] forKeyPath:@"finalBalance"];

Or if that object happens to have a setter for finalBalance that takes an int, you can just use that directly.

Code:
[object setFinalBalance:iNewValue];

Or if finalBalance is a property:

Code:
object.finalBalance = iNewValue;
 

elorc

macrumors newbie
Original poster
Apr 1, 2009
12
0
Ugh, I'm an idiot. lol. I forgot all about that, eddietr. That works exactly as I intended it to. Thank you!
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.