An NSOutlineView with an empty datasource doesn't invoke its delegate methods? - objective-c

Differently from a NSTableView, the delegate methods of an empty NSOutlineView are never invoked.
For instance, NSTableView method:
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex
is invoked even if there are not rows.
But, NSOutlineView method:
- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
is not invoked if there are not items.
I need to write arbitrary text on the first row of my outlineView when it is empty. But I can't use the above mentioned method like I do for NSTableView.
What's the solution ?
thanks

Have you implemented outlineView:numberOfChildrenOfItem: to give a correct answer when passed nil?
From your description it seems to me that it should return 1 (your initial line) when passed nil, but I can't be sure without more code and/or information.

Related

NSOutlineViewDelegate rowViewForItem being called with nil Item

I have a custom subclass of NSOutlineView in which I implement my own delegate method
- (NSTableRowView *)outlineView:(NSOutlineView *)outlineView rowViewForItem:(id)item
I've confirmed that the data source is set up correctly, and my implementation of the data source method
- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item
always returns the correct value.
When my program runs, the initialization runs smoothly, with the initial data structure being setup properly. However, as soon as the program gets into its first drawing cycle, it crashed on the heading line of - (NSTableRowView *)outlineView:(NSOutlineView *)outlineView rowViewForItem:(id)item { with message EXC_BAD_ACCESS. Looking at the data, I can see that item is nil.
Why would this be the case? If I'm setting up the data correctly, I don't see why a nil row item should be called.
Any suggestions?
Thanks!

Objective-C: Am I Properly Using this Delegate?

I have a mainWindowController that contains a tabView (which I'm using to switch between views on the main window).
I have view controllers (each with a nib file) for each view. One of the views, view A, contains a tableView. I need to use a delegate method to accomplish something.
After an hour or two or web research and reading up on delegates (new concept to me), I finally got my program to achieve the result I wanted it to for view A.
Here's the interface declaration for view A:
#interface ViewAController : NSViewController <NSTableViewDelegate>
- (BOOL) tableView:(NSTableView *)tableView shouldEditTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row;
As you can see, I'm using NSTableViewDelegate and I need to disable editing of table columns. The implementation looks like this for the method:
- (BOOL) tableView:(NSTableView *)tableView shouldEditTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
NSLog(#"shouldEditTableColumn called");
return NO;
}
I used NSLog to make sure the function is being called.
Now in the SAME view controller (view A), I disable editing by clicking a button:
- (IBAction)turnOffEditing:(id)sender
{
[self.tableView setDelegate:self];
[self tableView:self.tableView shouldEditTableColumn:self.columnTableName row:0];
[self tableView:self.tableView shouldEditTableColumn:self.columnTableName row:1];
NSLog(#"turnOffEditing");
}
As you can see, I get the tableView from the view controller and assign the delegate to self.
I then call the shouldEditTableColumn method on self.
Now, everything works. However, is this the correct way to use a delegate? If I need to use more delegate methods for NSTableView for view A (the only view which will have a table), I'm assuming I can define them in View A's controllers as I did previously?
Usually, the delegate is the delegate from the start. That is, it's a bit strange to set the delegate in the -turnOffEditing: action method. Of course, for my suggestion to work, you'd want to return some dynamic value, like the value of a boolean flag instance variable, from the delegate method.
Also, you shouldn't be calling the delegate method yourself in the action method. That does nothing. The delegate is a thing which the frameworks call when they need to make a decision about how to behave.
So, I'd change your code to something like:
#property BOOL editingDisabled;
- (BOOL) tableView:(NSTableView *)tableView shouldEditTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
NSLog(#"shouldEditTableColumn called");
return self.editingDisabled;
}
- (IBAction)turnOffEditing:(id)sender
{
self.editingDisabled = TRUE;
NSLog(#"turnOffEditing");
}
You'd want to set the delegate during setup. A good approach is to simply connect the table view's delegate outlet to your controller in the NIB.

Make NSTableView NOT edittable

OK, so here's my situation :
I've got an NSTableView.
Its columns are bound to an NSArrayController.
... which in turn is bound to an NSMutableArray.
However :
When the user click in any of the cells, he's allowed to edit their content.
We DON'T want that.
How should I do it, so that no table cells are editable?
In your NSTableViewDelegate return NO for this method:
- (BOOL)tableView:(NSTableView *)aTableView shouldEditTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex

NSImageCell: Set ToolTip

I'm trying to show a tooltip on the mouse hover at a NSImageCell. I've tried setting the property on Interface Builder (both on the NSImageCell and the NSTableColumn that contains it) but it didn't work.
Any ideas?
Neither NSCell nor NSTableColumn will display tool tips, because neither is a subclass of NSView. You will have to set the tool tip on the table view itself.
You can use -[NSView addToolTipRect:owner:userData:] to set a tool tip for a particular area of a view. In combination with -[NSTableView frameOfCellAtColumn:row:], you ought to be able to set up a different one for each cell.
I solved this by overriding this method in the controller for my NSOutlineView:
- (NSString *)outlineView:(NSOutlineView *)outlineView toolTipForCell:(NSCell *)cell rect:(NSRectPointer)rect tableColumn:(NSTableColumn *)tableColumn item:(id)item mouseLocation:(NSPoint)mouseLocation;
In case of NSTableView you can use
(NSString *)tableView:(NSTableView *)tableView toolTipForCell:(NSCell *)cell rect:(NSRectPointer)rect tableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row mouseLocation:(NSPoint)mouseLocation;

NSButtonCell as Checkbox in a NSTableVIew don't get selected

I have a NSTableVIew for multi-selection purposes with two columns, the first one with a NSButtonCell as checkbox and the other one as a title.
The idea is to check the items to be added afterwords to an array.
The problem is that the checkboxes don't change its state when I click them. I've tried to attach an IBAction but the sender to de action is the TableView but not the checkbox
Any ideas (or link) about how to achieve this kind of functionality?
Going on the assumption you're using a NSTableViewDataSource you need to implement three methods:
- (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView
When the checkbox is clicked the first method is called. If aTableColumn has your checkboxes you would save the new state, which is [anObject boolValue].
When the table needs to draw a row, it calls the second method. When the table column is your checkbox column, return the state that you saved in the first method.
The last method tells the table view how many rows there will be.
See the table data source documentation for more details, but I've pretty much summarized it here.