Newb question: Calculating values across a row in a NSTableView

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

  1. macrumors newbie

    Joined:
    Apr 1, 2009
    #1
    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. Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #2
    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. thread starter macrumors newbie

    Joined:
    Apr 1, 2009
    #3
    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?
     
  4. macrumors 6502a

    Joined:
    Oct 29, 2006
    Location:
    Virginia
    #4
    [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;
    
     
  5. thread starter macrumors newbie

    Joined:
    Apr 1, 2009
    #5
    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