How can you get indexes of visible rows for an NSOutlineView?
Asked Answered
K

4

9

How can you get a indexes of visible rows for an NSOutlineView? I need to know which level and which rows are visible.

[EDIT] What I'm actually looking for is an NSOutlineView equivalent to CocoaTouch/UITableView - (NSArray *)indexPathsForVisibleRows

Knothole answered 19/1, 2011 at 1:35 Comment(0)
K
0

I changed my datasource to return an NSIndexPath for outlineView:child:ofItem:. This way I could use [outlineview rowAtPoint:point] (and similar) to get the NSIndexPath.

This change required me to make a set of these indexPaths so they wouldn't get released until I don't need them. Also, all the other code which normally expected a model object now needs to lookup the model object from the index path. In my case this was efficient.

Knothole answered 19/1, 2011 at 3:39 Comment(1)
Still wish there was a indexPathsForVisibleRows equivalent.Knothole
E
23

you can do the following:

NSScrollView* scrollView = [self.tableView enclosingScrollView];

CGRect visibleRect = scrollView.contentView.visibleRect;

NSRange range = [self.tableView rowsInRect:visibleRect];

in the range you will get the location as the first visible cell and in the length the amount of cells are shown so you can know the index of the visible cells.

Edson answered 27/6, 2013 at 6:32 Comment(2)
Great answer! And then iterate over [self.tableView itemAtRow:range.location]Unpleasantness
Not sure how this is any different from the answer I posted nearly two and a half years earlier, aside from the unnecessary involvement of the scroll view (you can ask a view directly for its -visibleRect) and the fact the OP is asking about an outline view (tree) vs. a table (list)...Amorous
A
13

NSOutlineView is an NSTableView subclass. Therefore -rowsInRect: can be combined with -visibleRect (from NSView). Use -levelForRow: to determine the level.

Amorous answered 19/1, 2011 at 2:57 Comment(6)
Seems like you would have to iterate the model to count up to row number. I don't really want linear time.... Unless I'm missing something?Knothole
I'm not sure what you mean. You can translate rows to their real objects by itemForRow:, etc.Amorous
Sorry... My question wasn't detailed enough. I actually want to be able to get a tree coordinates for the visible rows. For example in my case the tree is has two levels so it would have two indexes for the leaf nodes.Knothole
Ah. I think I get your meaning. I don't believe there's a direct way to get an NSIndexPath from an item without building it by recursively asking the outline view for the -parentOfItem: until it responds with nil. For the few rows that would be on screen and only two levels deep though, I honestly don't believe you're facing a performance problem. Try then measure. :-)Amorous
This is also helpful for an NSTableView and loading images asynchronously.Setser
@Cal, the model is iterated only if you have dynamic heights for your rows. Otherwise, getting the rows in a visible rectangle is solved behind the scenes using a simple formula.Demagogy
K
0

I changed my datasource to return an NSIndexPath for outlineView:child:ofItem:. This way I could use [outlineview rowAtPoint:point] (and similar) to get the NSIndexPath.

This change required me to make a set of these indexPaths so they wouldn't get released until I don't need them. Also, all the other code which normally expected a model object now needs to lookup the model object from the index path. In my case this was efficient.

Knothole answered 19/1, 2011 at 3:39 Comment(1)
Still wish there was a indexPathsForVisibleRows equivalent.Knothole
O
0

In Swift 3:

let rows = IndexSet(integersIn: 0..<outlineView.numberOfRows)
let rowViews = rows.flatMap { outlineView.rowView(atRow: $0, makeIfNecessary: false) as? RowView }

for rowView in rowViews 
    //iterate over rows
}
Ottoman answered 16/9, 2017 at 3:9 Comment(2)
From the documentation for .rowView: "In general, makeIfNecessary should be (...) false if you want to update properties on a view only if it is available (generally this means it is visible)."A visible row is always available. However some rows could be ready to display or have leave the table and be available without being displayed a with this we could get them when we only want the visibles.Maymaya
OP asked for visible rowsCorporeity

© 2022 - 2024 — McMap. All rights reserved.