Customise table view cell in Mac app - cocoa

Am trying to customise a table view cell. I have created a separate nib file for the cell. Have added a Table view Cell in it with the customised layout ( 2 textfields and an image). All of them have an outlet.
In,
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
MyCell *myCell = [tableView makeViewWithIdentifier:#"cellId" owner:self];
myCell.text1.stringValue = #"Foo";
myCell.text2.stringValue = #"Bar";
return myCell;
}
I know this is wrong implementation, but how can I load a new nib for a cell in a tableView ?

Are you using
- (void)registerNib:(NSNib *)nib forIdentifier:(NSString *)identifier
to register your cell xibs?

Related

How can I add subclass to NSTableCellView?

I add an Image & Text Table Cell View to NSTable in IB. There is a TextFiled and a ImageView in the Text Table Cell View, so my code looks like this:
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row{
NSString *iden = [ tableColumn identifier ];
if ([iden isEqualToString:#"MainCell"]) {
NSTableCellView *cell = [ tableView makeViewWithIdentifier:#"MainCell11" owner:self ];
[cell.textField setStringValue:#"123"];
[cell.imageView setImage:[[NSImage alloc] initByReferencingFile:#"/Users/Pon/Pictures/17880.jpg"]];
return cell;
}
return nil;
}
I found that textfield and imageView has default outlet, so I can use cell.textFiled to visit this textField Object and change the value of it. Here is my question, if I add an extra TextField to this Image & Text Table Cell View, there is two TextField in one column, so how can I get the second TextFiled which added by me, change the TextFiled's value?
As it said at the NSTableCellView Class Reference page
Additional properties can be added by subclassing NSTableCellView and adding the required properties and connecting them programmatically or in Interface Builder.
Create your NSTableCellView-subclass (say 'CustomTableCellView'), define an additional text field outlet property (the image view and the first text field are defined in the super class). Set the class of your cell prototype in the Interface Builder and connect the additional text field control to your property.
In your NSTableViewDelegate class:
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row{
NSString *iden = [ tableColumn identifier ];
if ([iden isEqualToString:#"MainCell"]) {
CustomTableCellView *cell = [ tableView makeViewWithIdentifier:#"MainCell11" owner:nil ]; // use custom cell view class
[cell.textField setStringValue:#"123"];
[cell.imageView setImage:[[NSImage alloc] initByReferencingFile:#"/Users/Pon/Pictures/17880.jpg"]];
[cell.addinitionalField setStringValue:#"321"]; // that is all
return cell;
}
return nil;
}

Adding elements with content not working in NStable view in cocoa

I created a tableview and added image & text table view cell designed it now i thought to add another label in the row and assigned some values to the label based on the rows but it is not working and one more problem i cant hide label when the label in cell while in view i can able to hide
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
NSImage *profile=[NSImage imageNamed:#"header_menubg.png"];
NSString *identifer=[tableColumn identifier];
if([identifer isEqualToString:#"Mainidentifier"])
{
cellView = [tableView makeViewWithIdentifier:tableColumn.identifier owner:self];
[cellView.textField setStringValue:[_homearray objectAtIndex:row]];
[cellView.imageView setImage:profile];
return cellView;
}
if(row==0)
{
_countLabel.stringValue=#"40";
[cellView.textField setHidden:YES];
}
return nil;
}
And even i tried to hide text field in some rows that too not working what may be the problem

How to have checkboxes and textfields in a single tableview column using NSTableViewDataSource Protocol?

How can one have checkboxes and textfield (for section headings) in a single tableview column using NSTableViewDataSource Protocol?
My requirement is to use a Cell Based TableView.
I answered your other question without any code and i think you had trouble understanding it.
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
array = [[NSMutableArray alloc]initWithObjects:#0,#1,#2, nil];//instead this you can add your class object
[self.myTableView reloadData];
}
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
{
return [array count];
}
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
NSButtonCell * cell =[[NSButtonCell alloc]init];
[cell setButtonType:NSSwitchButton];
if([array objectAtIndex:row] == [NSNumber numberWithInt:0])
{
[tableColumn setDataCell:cell];
[[tableColumn dataCell]setTitle:#"Are you single?"];// instead this you can access title from your class object or from any other storage
}
else if ([array objectAtIndex:row] == [NSNumber numberWithInt:1])
{
[tableColumn setDataCell:[[NSTextFieldCell alloc]init]];
}
else if ([array objectAtIndex:row] == [NSNumber numberWithInt:2])
{
[tableColumn setDataCell:cell];
[[tableColumn dataCell]setTitle:#"Are you happy?"];
}
return [array objectAtIndex:row];
}
So thought this would help:) Cheers.
Here are the steps to make a single column tableview where the column can have row(s) that are section headings (NSTextFieldCells) followed by rows that are checkboxes (NSButtonCells) having descriptive titles. Similar to a listbox in MS MFC. To be compatible with older versions of OS X it needs to be a Cell based tableview:
Using IB drag a tableView control into the Application Window. In the Attributes inspector set Content Mode as "Cell Based", and Columns to 1.
Using IB drag a "Check Box Cell" control from the Object Library into the Application Window's column. (note: this step probably can be omitted since in the example code shown below, the cell type is being set explicitly to be either a NSButtonCell (checkbox) or NSTextFieldCell). If one needs to expand this example to use multiple columns, then probably want to set the Identifier for the NSTableColumn(s) in IB's Identity Inspector, in order that in the code one can filter by column/row instead of only by row (i.e. inside of the method objectValueForTableColumn).
Set the TableView's datasource and delegate to be the auto generated App Delegate object (in this case ApplicationAppDelegate.h). Do this by opening IB, and using the "Connection Inspector" click and drag from the datasource circle connection icon to the "App Delegate" object icon in the IB panel that shows objects that are loaded from the NIB such as controls, controllers etc.(icon for App Delegate is a blue cube). Do the same click and drag operation with the delegate circle icon.
Open the Assistant Editor, with the App Delegate's .h file showing in the left vertical pane and the IB view of the Table View in the right vertical pane. Select on the TableView control and create an IB outlet named "tableView" by holding the control key and dragging from the TableView Control to the section of the .h file where properties are listed.
Declare a NSMutableArray variable in the .h file. It should look like the following (Note: there has been added NSTableViewDataSource as a supported protocol of ApplicationAppDelegate):
#import <Cocoa/Cocoa.h>
#interface ApplicationAppDelegate : NSObject <NSApplicationDelegate,NSTableViewDataSource>
{
NSMutableArray *state;
}
#property (assign) IBOutlet NSWindow *window;
#property (weak) IBOutlet NSTableView *tableView;
#end
6 . Add the following functions to the App Delegate implementation file (.m):
#import "ApplicationAppDelegate.h"
#implementation ApplicationAppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
state = [[NSMutableArray alloc]initWithObjects:#"Section Heading:",#0,#1, nil];//Note: values passed to NSButtonCells should be 0 or 1 or YES or NO, and the state passed to NSTextFieldCell is a NSString
[self.tableView reloadData];
}
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
{
return [state count];
}
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
NSButtonCell * cell =[[NSButtonCell alloc]init];
[cell setButtonType:NSSwitchButton];
if (row == 0)
{
[tableColumn setDataCell:[[NSTextFieldCell alloc]init]];
}
else if (row == 1)
{
[tableColumn setDataCell:cell];
[[tableColumn dataCell]setTitle:#"title row1"];
}
else if (row == 2)
{
[tableColumn setDataCell:cell];
[[tableColumn dataCell]setTitle:#"title row2"];
}
return [state objectAtIndex:row];
}
- (void)tableView:(NSTableView *)tableView setObjectValue:(id)value forTableColumn:(NSTableColumn *)column row:(NSInteger)row
{
[state replaceObjectAtIndex:row withObject:value];
[tableView reloadData];
}
#end

NSViewController view's not released when used in a view based NSTableView

I have a view based NSTableView that uses the views of NSViewController subclasses (InspectorViewController) :
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
// Get inspector view controller
InspectorViewController *inspectorViewController = [_inspectorViewControllers objectAtIndex:row];
// Return its view
return inspectorViewController.view;
}
All is ok except that the view of NSViewController is never released when I remove the view controller (which is well released).
If I use this code instead :
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
// Get inspector view controller
InspectorViewController *inspectorViewController = [_inspectorViewControllers objectAtIndex:row];
// Return its view
NSTableCellView *view = [[NSTableCellView alloc] init] autorelease];
[view addSubview:inspectorViewController.view];
return view;
}
The view is correctly released when I remove the view controller.
Here is the code for removing a view controller :
- (void)inspectorViewControllerClosed:(InspectorViewController *)inspectorViewController {
// Get index of inspector view controller
NSUInteger index = [_inspectorViewControllers indexOfObject:inspectorViewController];
// Remove inspector view controller in array
[_inspectorViewControllers removeObject:inspectorViewController];
// Create index set
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:index];
// Begin updates
[_tableView beginUpdates];
// Move row in table view
[_tableView removeRowsAtIndexes:indexSet withAnimation:NSTableViewAnimationEffectFade];
// End updates
[_tableView endUpdates];
}
I tried to reproduce the problem with a small sample code and I have the same problem, the view of view controller is only released when I don't return directly the view of view controller.
Anybody can help me please ?
Found, NSTableView retains view for reusing, it is correctly released with this code :
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
// Get inspector view controller
InspectorViewController *inspectorViewController = [_inspectorViewControllers objectAtIndex:row];
// Disable reusing ?
[_inspectorViewController.view setIdentifier:nil];
// Return its view
return inspectorViewController.view;
}
You could use:
[inspectorViewController.view removeFromSuperview]
before removing the view controller.

CheckBox in tableview

I am facing trouble in putting check boxes into a UITableView. I am posting a part of my code here.
- (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
NSButtonCell *cell=[[NSButtonCell alloc] init];
NSString *strDisplayPlaylistName;
strDisplayPlaylistName=[playListNameArray objectAtIndex:row];
[cell setTitle:strDisplayPlaylistName];
[cell setAllowsMixedState:YES];
[cell setButtonType:NSSwitchButton];
return cell;
}
- (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex {
NSCell *aCell = [aTableColumn dataCellForRow:rowIndex];
[aCell setNextState];
//NSCell *aCell=[aAddedCells objectAtIndex:rowIndex];
//[aCell setNextState];
}
I got the checkboxes inside the UITableView. But the problem is that I can't uncheck the buttons. Is there anything more to do. I am new to cocoa programming.
You're missing a couple of important pieces. You need to update your model (data stcuture) in response to the tableValue:setObjectValue:forTableColumn:row: message, so that you can correctly return the new value from tableView:objectValueForTableColumn:row: method.
Here are some table data source methods assuming you have a 'myRows' array filled with objects with a 'booleanAttribute' property.
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
return [myRows count];
}
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
BOOL value = [[myRows objectAtIndex:row] booleanAttribute];
return [NSNumber numberWithInteger:(value ? NSOnState : NSOffState)];
}
- (void)tableView:(NSTableView *)tableView setObjectValue:(id)value forTableColumn:(NSTableColumn *)column row:(NSInteger)row {
[[myRows objectAtIndex:row] setBooleanAttribute:[value booleanValue]];
}
You should also setup your table cell in interface builder. You can drag a button cell configured like a standard check box directly onto one of your table columns.
I'm not sure why you're creating the cell in code. You can just drag the cell onto the table column in Interface Builder.
Also, setObjectValue: is where you respond to the change in the cell's state. The user has already changed the cell's state to off; then you send setNextState and change it back. That's why the cell doesn't appear to uncheck: you keep re-checking it.
What you need to do is not touch the cell at all, but set the object value (which, for this column, will probably be a Boolean NSNumber containing either YES or NO) as the new value of the appropriate property in your model.
Also, of course, make sure the column is set as editable.
If you have your NSTableView content mode set to "Cell Based" it will be "View Based" when you move the checkbox over.

Resources