Newb question: Calculating values across a row in a NSTableView

Discussion in 'Mac Programming' started by elorc, Apr 10, 2009.

  1. elorc macrumors newbie

    Apr 1, 2009
    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. :)
  2. kainjow Moderator emeritus


    Jun 15, 2000
    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.
  3. elorc thread starter macrumors newbie

    Apr 1, 2009
    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.

    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    	if ([keyPath isEqual:@"finalBalance"])
    		NSLog(@"No need to update for finalBalance.");
    	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");
    		// 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 
    	[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?
  4. eddietr macrumors 6502a

    Oct 29, 2006
    [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:

    [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.

    [object setFinalBalance:iNewValue];
    Or if finalBalance is a property:

    object.finalBalance = iNewValue;
  5. elorc thread starter macrumors newbie

    Apr 1, 2009
    Ugh, I'm an idiot. lol. I forgot all about that, eddietr. That works exactly as I intended it to. Thank you!

Share This Page