Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using NSTableView Animations with Bindings

I have a NSTableView that is bound to a NSArrayController. The NSArrayController's contentSet property is bound to a NSMutableSet. Everything works great.

Now I want to use the animations built in to NSTableView to remove rows. I can do this with - [NSTableView removeRowsAtIndexes:withAnimation:] and the row quickly animates away, however the object I removed from the tableview is still hanging out in the NSMutableSet that is backing the tableview. Obviously I need to remove it. If I try to remove it through the NSArrayController's removeObject: method then the object disappears from the tableview immediately which means the animation doesn't occur or gets cut off halfway through.

Bindings work wonders and make things so much easier but what exactly is the proper method for keeping the data source and tableview in sync when both bindings and NSTableView animations are being used? The answer should also address how to add rows to a bound NSTableView using animations.

like image 429
Carter Avatar asked Nov 24 '12 13:11

Carter


2 Answers

The model needs to be updated right after the animation is complete:

@IBAction func onRemoveClick(sender: AnyObject?) {
    let selection = listController.selectionIndexes
    NSAnimationContext.runAnimationGroup({
        context in
        self.tableView.removeRowsAtIndexes(selection, withAnimation: .EffectFade | .SlideUp)
    }, completionHandler: {
        self.listController.removeObjectsAtArrangedObjectIndexes(selection)
    })
}

Works in my app with bindings. Tested on OS X 10.9, 10.10 & 10.11.

like image 158
pointum Avatar answered Sep 24 '22 21:09

pointum


I've just been playing with this on OS X 10.9, and everything seems to be working fine for me. Here's my code (I have a '-' button in each row of my view-based table:

- (IBAction)removeRow:(id)sender {
    NSUInteger selectedRow = [self.myTable rowForView:sender];
    if (selectedRow == -1) {
        return;
    }
    [self.myTable removeRowsAtIndexes:[NSIndexSet indexSetWithIndex:selectedRow] withAnimation:NSTableViewAnimationSlideUp];
    [self.myArrayHookedUpToTheNSArrayController removeObjectAtIndex:selectedRow];
}

Maybe something changed in 10.9? All of this is running from the main thread, could that be why? (Have you tried calling the code inside a dispatch_async(dispatch_get_main_queue(), block())?

like image 32
Patrick Avatar answered Sep 20 '22 21:09

Patrick