Thank you for all your feedback Claude.
I posted the following as the second item in this thread, however it seems to have got stuck at moderation.
Posting again with a github link removed....
_____________________________
I first noticed the issue in my large project, but was able to reproduce it quickly in someone else's simple example project from GitHub called "OutlineViewReorder" - that you Thierry!
To repro, I added the following items to the Edit menu:
- Hide row index 2
- Check hidden indexes
- Unhide row index 2
These link to the following methods on the view controller as the first responder:
@IBAction func hideRow(_ sender: AnyObject) {
print("Hiding row \(hideIndex)")
theOutline.hideRows(at: [hideIndex], withAnimation: [])
}
@IBAction func checkHiddenRows(_ sender: AnyObject) {
print("Hidden row check \(theOutline.hiddenRowIndexes)")
}
@IBAction func unhideRow(_ sender: AnyObject) {
print("unHiding row \(hideIndex)")
theOutline.unhideRows(at: [hideIndex], withAnimation: [])
}
I updated the outline view delegate to the following:
extension ViewController: NSOutlineViewDelegate {
func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
let cell = outlineView.make(withIdentifier: "OutlineColItem", owner: self) as! OutlineItemView
cell.textField!.delegate = self
if let folderItem = item as? FolderItem
{
cell.textField!.stringValue = folderItem.name
cell.imageView!.image = folderImage
}
else if let aItem = item as? TestItem
{
cell.textField!.stringValue = aItem.name
cell.imageView!.image = itemImage
}
print("View for item called")
return cell
}
func outlineView(_ outlineView: NSOutlineView, didAdd rowView: NSTableRowView, forRow row: Int) {
print("Row added at index: \(row). Hidden row indexs: \(outlineView.hiddenRowIndexes)")
}
func outlineView(_ outlineView: NSOutlineView, didRemove rowView: NSTableRowView, forRow row: Int) {
print("Row removed with index: \(row). Hidden row indexs: \(outlineView.hiddenRowIndexes)")
}
func outlineView(_ outlineView: NSOutlineView, rowViewForItem item: Any) -> NSTableRowView? {
print("Row view requested")
return NSTableRowView()
}
func outlineView(_ outlineView: NSOutlineView, heightOfRowByItem item: Any) -> CGFloat {
print("Row height requested")
return 20
}
}
In the outline data source I have simply added a print to the draggingSession:willBegineAt call:
func outlineView(_ outlineView: NSOutlineView, draggingSession session: NSDraggingSession, willBeginAt screenPoint: NSPoint, forItems draggedItems: [Any]) {
print("Dragging session will begin with hidden row indexes: \(outlineView.hiddenRowIndexes)")
draggedNode = draggedItems[0] as AnyObject?
session.draggingPasteboard.setData(Data(), forType: REORDER_PASTEBOARD_TYPE)
}
I start the app and it builds the view.
I use my "Hide index 2" menu item and get the following output
Hiding row 2
Row removed with index: -1. Hidden row indexs: 1 indexes
Row view requested
Row height requested
Row height requested
View for item called
Row height requested
Row added at index: 2. Hidden row indexs: 1 indexes
I can now check the hidden indexes with my other menu item:
Hidden row check 1 indexes
I now start to drag one of the other rows in the outline view. As I move the mouse I get the following output:
Row height requested
Dragging session will begin with hidden row indexes: 0 indexes
...and the hidden row animated into view.
Now, it is possible to hack in a re-hide of the rows in draggingSession:willBegineAt, assuming that I am tracking my own hidden items...
func outlineView(_ outlineView: NSOutlineView, draggingSession session: NSDraggingSession, willBeginAt screenPoint: NSPoint, forItems draggedItems: [Any]) {
print("Dragging session will begin with hidden row indexes: \(outlineView.hiddenRowIndexes)")
draggedNode = draggedItems[0] as AnyObject?
session.draggingPasteboard.setData(Data(), forType: REORDER_PASTEBOARD_TYPE)
print("Hiding row in dragginSession:willBeginAt \(2)")
theOutline.hideRows(at: [2], withAnimation: [])
}
func outlineView(_ outlineView: NSOutlineView, draggingSession session: NSDraggingSession, endedAt screenPoint: NSPoint, operation: NSDragOperation) {
print("Dragging session will END with hidden row indexes: \(outlineView.hiddenRowIndexes)")
self.draggedNode = nil
}
Now, I get the following output when I start dragging:
Row height requested
Dragging session will begin with hidden row indexes: 0 indexes
Hiding row in dragginSession:willBeginAt 2
Row removed with index: -1. Hidden row indexs: 1 indexes
Row view requested
Row height requested
Row height requested
View for item called
Row height requested
Row added at index: 2. Hidden row indexs: 1 indexes
Then, when dragging ends I get the following as the hidden row appears again:
Dragging session will END with hidden row indexes: 1 indexes
Row height requested
Then, when I check the indexes again using my menu item:
Hidden row check 0 indexes
So, I am a bit stumped as how to work round this. I could live with a re-hide call in draggingSessionWillBegin, but I have nowhere to catch the unhide AGAIN on end drag - since the hiddenIndexes are correct at that point, and unhidden imediately afterwards.
...and this is surely a bug.
Please let me know if there is anything else ambiguous that I am doing here.
Thanks again.