3

I have an app that shows "chapters and pages" in an NSOutlineView.

To make it clear to the user that "chapters" can contain "pages", I'd like the outline view to always show the disclosure triangle for chapters, even if they have no pages in them (i.e. are empty).

Here's an example:

enter image description here

Note how the first chapter is empty (no pages) and has no disclosure triangle.

I'd like the triangle to show up so that when users click on it, they realize that this is a "container" item that can contain other items.

I tried implementing various delegate methods, but could not get the disclosure triangle to show for empty entries.

Sample project: https://www.dropbox.com/s/fdggjod78t0isjr/OutlineViewTest.zip?dl=0

Daniyar
  • 2,975
  • 2
  • 26
  • 39
Mark
  • 6,647
  • 1
  • 45
  • 88
  • How did you implement `- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item` NSOutlineView delegate method? – Daniyar Apr 17 '15 at 08:37
  • I implemented `isItemExpandable:` to return YES all the time. However, it is not called for items with no children. – Mark Apr 17 '15 at 10:19
  • Can you provide your code? I'm interested in `NSOutlineViewDataSource` methods. – Daniyar Apr 17 '15 at 11:11
  • @Astoria I added a link to the sample project. – Mark Apr 17 '15 at 12:18

2 Answers2

3

Ok, now I see. You're using Cocoa Bindings which assumes that some of the dataSource methods shouldn't get called. As displayed at the NSOutlineViewDataSource reference page

'- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item'

IMPORTANT

While this method is marked as @optional in the protocol, you must implement this method if you are not providing the data for the outline view using Cocoa bindings.

Just try to implement it without Cocoa Bindings. Or you can find the way to break into the binding process and find out how to reject disclosure button deletion.

Yep, there's a third way. You can create MyTableCellView.xib and add your own disclosure button as well.

UPD

To determine, which item should have disclosure triangle, there's a Leaf key path at the Tree Controller attributes inspector tab.

enter image description here

Don't forget to add models' values to your data like that

@{@"title": @"Chapter 1 (empty)", @"isLeaf":@(NO)}

enter image description here

Daniyar
  • 2,975
  • 2
  • 26
  • 39
  • Thanks for your suggestion. Implementing without bindings is not really an option as this would make my app more complicated (it's a fairly large app already). Adding my own button might work, but also does not seem quite right. I'm still hoping that there's a way through extending NSOutlineView or some delegate method... – Mark Apr 17 '15 at 13:39
1

You need to implement the NSOutlineViewDelegate outlineView:shouldShowOutlineCellForItem: and have it return YES.

- (BOOL)outlineView:(NSOutlineView *)outlineView shouldShowOutlineCellForItem:(id)item {
    return YES;
}

The "outline cell" is the disclosure triangle. You need this in addition to returning YES for isExpandable.

The method's reference says:

Returning NO causes frameOfOutlineCellAtRow: to return NSZeroRect

And the 1st answer here about how to change the triangle image seems to indicate that the frame gets used for both cell and view-based outline views, so this method should work for both. (Note that the easier solution is the 2nd answer there.)

This answer is wiki... I suspect I missed something.

Community
  • 1
  • 1
stevesliva
  • 5,351
  • 1
  • 16
  • 39