Cocoa NSView in NSTableView Cell
Asked Answered
M

3

6

I'm new to cocoa and I'm getting frustrated, I've spent almost half the day trying to find out how to add an NSView to a NSTableView cell, but I haven't found a nice guide that can help me do what I would like to achieve, maybe someone can have a look at what I've tried and tell me why it's not working and how I could get it to work...

-(NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row{
NSTableCellView *view = [tableView makeViewWithIdentifier:@"MyView" owner:self];
NSTextField *textfield = [[NSTextField alloc]initWithFrame:NSMakeRect(0, 0, 100, 30)];
[textfield setStringValue:predictate_search[row]];
[textfield setBackgroundColor:[NSColor redColor]];
[view addSubview:textfield];
[view setNeedsDisplay:YES];
return view;
}

What I would like to achieve is to have two NSTextFields above each other and the table cell to have a custom background. The above is me just trying to get one NSTextField to work, but with no luck...

The NSTableView is being created programmatically:

NSScrollView *scrollView = [[NSScrollView alloc]initWithFrame:bg];
    [scrollView setHasVerticalScroller:YES];
    [self addSubview:scrollView];

    search_results = [[NSTableView alloc]initWithFrame:bg];
    NSTableColumn *column = [[NSTableColumn alloc] initWithIdentifier:@"id"];
    [[column headerCell] setStringValue:@"Cities"];
    [column setWidth:1000.0];

    [search_results addTableColumn:column];
    [search_results setDelegate:(id)self];
    [search_results setDataSource:(id)self];
    [search_results reloadData];

    [scrollView setDocumentView:search_results];

I'm slightly confused what to put for the makeViewWithIdentifier:, I've watched the WWDC 2011 video on NSTableViews but I'm still not really sure.

If you require more information please ask

Thanks

EDIT After first answer:

-(NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row{
NSTableCellView *view = [tableView makeViewWithIdentifier:[tableColumn identifier] owner:self];
if(view == nil){
    NSTableCellView *view = [[NSTableCellView alloc]initWithFrame:[tableView frame]];
    view.identifier = [tableColumn identifier];
}
NSTextField *textfield = [[NSTextField alloc]initWithFrame:NSMakeRect(0, 0, 100, 30)];
[textfield setStringValue:predictate_search[row]];
[textfield setBackgroundColor:[NSColor redColor]];
[view addSubview:textfield];
[view setNeedsDisplay:YES];
return view;

}

However it is still not working?

Mamie answered 11/11, 2012 at 18:33 Comment(0)
M
1

your method that returns the cell must make the cell if it isnt dequeable (because none is there)

// There is no existing cell to reuse so we will create a new one
if (result == nil) {

     // create the new NSTextField with a frame of the {0,0} with the width of the table
     // note that the height of the frame is not really relevant, the row-height will modify the height
     // the new text field is then returned as an autoreleased object
     result = [[[NSTextField alloc] initWithFrame:...] autorelease];

     // the identifier of the NSTextField instance is set to MyView. This
     // allows it to be re-used
     result.identifier = @"MyView";
  }
Monger answered 11/11, 2012 at 18:53 Comment(4)
just checking ... you did implement the other methods? :: developer.apple.com/library/mac/#documentation/Cocoa/Reference/…Monger
I have implemented the - (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView as far as I know it's the only compulsory one...Mamie
uff.. the easiest would be if you provided the source and I/we could take a look.. nothing is catching my eye right nowMonger
I managed to figure it out... somehow, I still don't know how but it works I'll mark your answer as right as it did help ;), I'll also post my solution if your interested!Mamie
M
7

The code below solved my problem:

-(NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row{
NSView *view = [tableView makeViewWithIdentifier:@"MyView" owner:self];

if (view == nil) {
    view = [[NSView alloc]initWithFrame:NSMakeRect(0, 0, 100, 30)];
    NSTextField *result = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 25, 800, 25)];
    NSTextField *result2 = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 800, 25)];
    result.stringValue = [predictate_search objectAtIndex:row];
    result2.stringValue = @"UnitedKingdom";
    [view addSubview:result];
    [view addSubview:result2];
    [view setNeedsDisplay:YES];
}

return view;

}

Thanks for helping :)

Mamie answered 11/11, 2012 at 20:8 Comment(0)
M
1

your method that returns the cell must make the cell if it isnt dequeable (because none is there)

// There is no existing cell to reuse so we will create a new one
if (result == nil) {

     // create the new NSTextField with a frame of the {0,0} with the width of the table
     // note that the height of the frame is not really relevant, the row-height will modify the height
     // the new text field is then returned as an autoreleased object
     result = [[[NSTextField alloc] initWithFrame:...] autorelease];

     // the identifier of the NSTextField instance is set to MyView. This
     // allows it to be re-used
     result.identifier = @"MyView";
  }
Monger answered 11/11, 2012 at 18:53 Comment(4)
just checking ... you did implement the other methods? :: developer.apple.com/library/mac/#documentation/Cocoa/Reference/…Monger
I have implemented the - (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView as far as I know it's the only compulsory one...Mamie
uff.. the easiest would be if you provided the source and I/we could take a look.. nothing is catching my eye right nowMonger
I managed to figure it out... somehow, I still don't know how but it works I'll mark your answer as right as it did help ;), I'll also post my solution if your interested!Mamie
T
1

Well, just looking at this, I'm going to add in an answer just in case someone stumbles over this in the future.

view is defined in the second line of the code snippet. If it's nil, it drops into the if statement and view is defined again. The view that comes out of the in statement disappears because it was defined within the scope of the bracket and dies when the program leaves that scope leaving you the original nil.

Now there may be lots more problems with this but that sticks out. I was doing some research on the subject and found this question and noticed the scoping problem.

Testa answered 23/1, 2017 at 14:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.