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. :)
 
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.
 
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?
 
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;
 
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.