Nitin Gohel
Nitin Gohel

Reputation: 49710

Multiple NSTableCellView in one NSTableviewColumn Cocoa OSX

I am trying to create a NSTableview with different cells in one column. I am setting two NSTableCellView's in one column like so:

enter image description here

And setting the data code like so:

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
    // Get a new ViewCell

    // Since this is a single-column table view, this would not be necessary.
    // But it's a good practice to do it in order by remember it when a table is multicolumn.
    if( [tableColumn.identifier isEqualToString:@"BugColumn"] )
    {
           NSMutableDictionary *dic =(NSMutableDictionary*)[self.ArraRecentDataLoad objectAtIndex:row];

        if([[dic valueForKey:@"type"] isEqualToString:@"image/png"] || [[dic valueForKey:@"type"] isEqualToString:@"image/jpeg"])
        {

         ImageCell *cellView = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];

                cellView = [[ImageCell alloc] initWithFrame:NSMakeRect(0, 0, 316, 313)];

                // This allows the cell to be reused.
                cellView.identifier =tableColumn.identifier;

            NSColor *orangeColor = [NSColor colorWithCGColor:[NSColor colorWithRed:240/255.0f green:240/255.0f blue:240/255.0f alpha:1.0f].CGColor];

            // Convert to CGColorRef
            NSInteger numberOfComponents = [orangeColor numberOfComponents];
            CGFloat components[numberOfComponents];
            CGColorSpaceRef colorSpace = [[orangeColor colorSpace] CGColorSpace];
            [orangeColor getComponents:(CGFloat *)&components];
            CGColorRef orangeCGColor = CGColorCreate(colorSpace, components);
            [cellView.bgCellview setWantsLayer:YES];
            cellView.bgCellview.layer.masksToBounds= YES;
            cellView.bgCellview.layer.borderWidth=2;
            // Set border
            cellView.bgCellview.layer.borderColor = orangeCGColor;

            // Clean up
            CGColorRelease(orangeCGColor);

            return cellView;
        }
        else
        {
             HomeCell *cellView = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];

            NSColor *orangeColor = [NSColor colorWithCGColor:[NSColor colorWithRed:240/255.0f green:240/255.0f blue:240/255.0f alpha:1.0f].CGColor];

            // Convert to CGColorRef
            NSInteger numberOfComponents = [orangeColor numberOfComponents];
            CGFloat components[numberOfComponents];
            CGColorSpaceRef colorSpace = [[orangeColor colorSpace] CGColorSpace];
            [orangeColor getComponents:(CGFloat *)&components];
            CGColorRef orangeCGColor = CGColorCreate(colorSpace, components);
            [cellView.bgview setWantsLayer:YES];
            cellView.bgview.layer.masksToBounds= YES;
            cellView.bgview.layer.borderWidth=2;
            // Set border
            cellView.bgview.layer.borderColor = orangeCGColor;

            // Clean up
            CGColorRelease(orangeCGColor);

            return cellView;
        }

    }
    return nil;
}

But in my xib if I drag a second cell (imageCell) then my app crashes with unrecognized select. If I do it like the above screenshot, then I am not able to load a second cell and there is white space in NSTableview.

I do lots of RND but I am not able to find a proper way to use different cells in a single column and load as per conditional data.

Note:

If I remove alloc cell in first condition:

 cellView = [[ImageCell alloc] initWithFrame:NSMakeRect(0, 0, 316, 313)];
 cellView.identifier =tableColumn.identifier;

Then that shows the first row's pre-define labels instead of second ImageCell predefine like iOS.

Upvotes: 2

Views: 1288

Answers (2)

ERbittuu
ERbittuu

Reputation: 978

See first of all make it view base table view from nib. Then in viewfortablecolumn put conditions like of image, then check first of view(image cell or home cell make it simple NSView) available for image type then use it or alloc using makeviewusingidentifire or what ever you use and return that view. On second condition you have do same for that.

For every time call this method it will check first which type of view (image cell or home cell in this particular) it wants then check if it was available in memory then use it if not then alloc and use it.

Let me know if any problem on this. Sry for bad English

Upvotes: 1

Ken Thomases
Ken Thomases

Reputation: 90521

The two cell views need to have different identifiers. You will have to manually assign at least one of them. You can't let Xcode automatically assign both. (I'm not even sure if Xcode will let you configure things that way.)

Then, you need to use the proper identifier when you call [tableView makeViewWithIdentifier:... owner:self]. At most one of those calls can use the table column's identifier. The other must use the manually-assigned one.

If you put both cell views in the NIB (with separate identifiers) and fetch them using [tableView makeViewWithIdentifier:... owner:self], then you don't need to alloc/init one programmatically (and you shouldn't). If you prefer to alloc/init one programmatically, you must assign a different identifier for it. Again, you can't have two separate cell view types with the same identifier.


Update: Let me try again in simpler form. Do this:

  • In the NIB, select the Image Cell view. On the Identity inspector, set the identifier to "ImageCell".
  • In your code, for the image branch, do ImageCell *cellView = [tableView makeViewWithIdentifier:@"ImageCell" owner:self]; instead of using the table column identifier.
  • Remove the following two statements which allocate a new instance of the ImageCell class and sets its identifier property.

So, the code should look like this:

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
    // Get a new ViewCell

    // Since this is a single-column table view, this would not be necessary.
    // But it's a good practice to do it in order by remember it when a table is multicolumn.
    if( [tableColumn.identifier isEqualToString:@"BugColumn"] )
    {
        NSMutableDictionary *dic =(NSMutableDictionary*)[self.ArraRecentDataLoad objectAtIndex:row];

        if([[dic valueForKey:@"type"] isEqualToString:@"image/png"] || [[dic valueForKey:@"type"] isEqualToString:@"image/jpeg"])
        {
            ImageCell *cellView = [tableView makeViewWithIdentifier:@"ImageCell" owner:self];

            NSColor *orangeColor = [NSColor colorWithCGColor:[NSColor colorWithRed:240/255.0f green:240/255.0f blue:240/255.0f alpha:1.0f].CGColor];
            // ...

Upvotes: 3

Related Questions