Problems faced while customizing NSTextFieldCell

Discussion in 'Mac Programming' started by Monaj, Feb 1, 2010.

  1. Monaj macrumors regular

    May 24, 2009
    Hi all,

    I am trying to make cells in an outline view just like we have for users in Skype's message window.

    For this I created a custom class:


     @interface IconNameCell : NSTextFieldCell {
            NSImage *userImage;  // size (17,17)
            NSImage *statusIcon; // size (14,14)
            NSString *cellText;
        @property (readwrite, retain) NSImage *userImage;
        @property (readwrite, retain) NSImage *statusIcon;
        @property (readwrite, retain) NSString *cellText;
        - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView;

    @implementation IconNameCell
    @synthesize userImage;
    @synthesize statusIcon;
    @synthesize cellText;
    - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView{
        // Inset the cell frame to give everything a little horizontal padding
        NSRect anInsetRect = NSInsetRect(cellFrame,2.0,0); 
        //FIXME: flip coordinates and size can be set in accessor methods
        // setting userImage and statusIcon in flipped coordinate 
        [userImage setFlipped:YES];
        [statusIcon setFlipped:YES];
        // setting size of image and icon
        [userImage setSize:NSMakeSize(25.0, 25.0)];
        [statusIcon setSize:NSMakeSize(15.0, 17.0)];
        // setting attributes of cell text
        NSMutableParagraphStyle *dParagraphStyle = [[NSMutableParagraphStyle alloc] init];
        [dParagraphStyle setAlignment:NSLeftTextAlignment];
        NSColor *colorOfText;
        if ([self isHighlighted]) {
            colorOfText = [NSColor whiteColor]; 
        else {
            colorOfText = [NSColor blackColor];
        NSMutableDictionary * dTitleAttributes = [[NSMutableDictionary alloc] initWithObjectsAndKeys:
                                                   [NSFont systemFontOfSize:11.0],NSFontAttributeName,
                                                   dParagraphStyle, NSParagraphStyleAttributeName,
        // getting sizes
        NSSize cellTextSize = [cellText sizeWithAttributes:dTitleAttributes];
        NSSize userImageSize = [userImage size];
        NSSize statusIconSize = [statusIcon size];
        // making layout boxes for all elements
        // vertical padding between the lines of text
        float dVerticalPadding = 2.0;
        // horizontal padding between two images
        float padBtwnImgs = 4.0;
        // horizontal padding between image and text
        float padBtwnImgText = 6.0;
            NSString *userImageName = [userImage name];
            NSLog(@"userImageName - %@ / cellText- %@",userImageName,cellText); // getting null for userImageName
            //if ([userImageName isEqualToString:@"current_D.png"]) {
            //FIXME: this is juggad and should be corrected 
            NSRange rangeOfComma = [cellText rangeOfString:@","];
            if (rangeOfComma.length !=0 ) {
            // userImage box: center the userImage vertically inside of the inset rect
            NSRect cellTitleBox = NSMakeRect(anInsetRect.origin.x,
                                             anInsetRect.origin.y + anInsetRect.size.height*.5 - cellTextSize.height*.5,
            // drawing cell text
            [cellText drawInRect:cellTitleBox withAttributes:dTitleAttributes];
        else {
            // userImage box: center the userImage vertically inside of the inset rect
            NSRect userImageBox = NSMakeRect(anInsetRect.origin.x,
                                             anInsetRect.origin.y + anInsetRect.size.height*.5 - userImageSize.height*.5,
            // statusIcon box: center the statusIcon vertically inside of the inset rect
            NSRect statusIconBox = NSMakeRect(userImageBox.origin.x + userImageBox.size.width + padBtwnImgs,
                                              anInsetRect.origin.y + anInsetRect.size.height*.5 - statusIconSize.height*.5,
            // cellTitleBox: vertically aligning text
            NSRect cellTitleBox = NSMakeRect(statusIconBox.origin.x + statusIconBox.size.width + padBtwnImgText,
                                             anInsetRect.origin.y + anInsetRect.size.height*.5 - cellTextSize.height*.5,
            // drawing user image
            [userImage drawInRect:userImageBox fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
            // drawing user status
            [statusIcon drawInRect:statusIconBox fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
            // drawing cell text
            [cellText drawInRect:cellTitleBox withAttributes:dTitleAttributes];
        @catch (NSException *e) {
            NSLog(@"IconNameCell -%@",e);
    2nd, I assigned text field cell for outline view the class: IconNameCell in IB

    3rd, I used this code in delegate to set image, icon and name of user in custom cell-

     - (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item{
            if ([[tableColumn identifier] isEqualToString:@"userInfo"]) {
              // some relevant code
              if( [[item onlineStatus] intValue] == 0 ){
            [cell setStatusIcon:[NSImage imageNamed:@"offline.png"]];
            [cell setStatusIcon:[NSImage imageNamed:@"online.png"]];
            //similarly, setting attribute for userImage and cellText
    I am facing two problems with it: 1. Application is frequently crashing when I am selecting one or the other row in outline view. Earlier when I had not taken the customized cell but three different columns for - user image, user status and user name it was working fine! 2. For the log: NSLog(@"userImageName - %@ / cellText- %@",userImageName,cellText); I am getting (null) as userImageName, although I should get some string value for it.

    Can anyone suggest me some solution for it??


  2. kainjow Moderator emeritus


    Jun 15, 2000
    What does the crash log show?

    You don't have a dealloc method in your cell. You're just leaking memory.

    Edit: you're also leaking the dictionary and attributed string.

Share This Page