2011-11-22 27 views
9

Tengo una vista basada en NSTableView que a veces filtro usando NSPredicate. ¿Hay alguna manera de animar los elementos que se eliminan/agregan/reordenan en el tableview para tener el mismo efecto que beginUpdates, endUpdates y insertRowsAtIndexes:withAnimation, etc.?Filtrado + animación NSTableView basada en la vista

He explorado formas como filtrar manualmente mi matriz, pero mis intentos demostraron ser inútiles, así que ahora me pregunto si hay una mejor (o integrada) para hacer esto. Me he preguntado si NSArrayController hace esto automáticamente, pero no creo que lo haga.

+2

No hay nada construido en el, me temo - por desgracia. –

+0

¡NSCollectionView es compatible con esta versión de fábrica! – bijan

+0

Lo más parecido que he visto es para tablas basadas en celdas: http://www.mactech.com/articles/mactech/Vol.18/18.11/1811TableTechniques/index.html – sbooth

Respuesta

5

He escrito el código para hacer esto yo mismo - dado arreglos 'antes' y 'después', calcule los parámetros requeridos a insertRowsAtIndexPaths:, deleteRowsAtIndexPaths:, etc. El código es un poco complicado, probablemente tenga errores - use a su discreción !

@interface NSArray (ArrayDifference) 
    - (void) computeDifferenceTo:(NSArray *)newArray returningAdded:(NSMutableArray **)rowsAdded andDeleted:(NSMutableArray **)rowsDeleted; 
@end 

@implementation NSArray (ArrayDifference) 

// Given two arrays that are expected have items added or removed but not re-ordered, compute the differences 
// in a way usable for UITable insertRows and deleteRows 
- (void) computeDifferenceTo:(NSArray *)newArray returningAdded:(NSMutableArray **)rowsAdded andDeleted:(NSMutableArray **)rowsDeleted 
{ 
    NSArray *oldArray = self; 
    *rowsAdded = [[[NSMutableArray alloc] init] autorelease]; 
    *rowsDeleted = [[[NSMutableArray alloc] init] autorelease]; 

    NSUInteger oldCount = [oldArray count]; 
    NSUInteger newCount = [newArray count]; 
    // Step through the two arrays 
    NSInteger oldIndex = 0, newIndex=0; 
    for (; newIndex < newCount && oldIndex < oldCount;) 
    { 
    id newItem = [newArray objectAtIndex:newIndex]; 
    id oldItem = [oldArray objectAtIndex:oldIndex]; 
    // If the two objects match, we step forward on both sides 
    if (newItem == oldItem) { 
     ++newIndex; 
     ++oldIndex; 
    } 
    else { 
     // Look for the old item to appear later in the new array, which would mean we have to add the rows in between 
     NSRange range = { newIndex+1, newCount - newIndex-1 }; 
     NSUInteger foundIndex = [newArray indexOfObject:oldItem inRange:range]; 
     if (foundIndex != NSNotFound) 
      for (; newIndex < foundIndex; ++newIndex) 
       [*rowsAdded addObject:[NSIndexPath indexPathForRow:newIndex inSection:0]]; 
     else { 
      // Look for the new item to appear later in the old array, which would mean we have to remove the rows in between 
      NSRange range = { oldIndex+1, oldCount - oldIndex-1 }; 
      NSUInteger foundIndex = [oldArray indexOfObject:newItem inRange:range]; 
      if (foundIndex != NSNotFound) 
       for (; oldIndex < foundIndex; ++oldIndex) 
        [*rowsDeleted addObject:[NSIndexPath indexPathForRow:oldIndex inSection:0]]; 
      else { 
       // Old item must be removed and new item added, then we carry on 
       [*rowsAdded addObject:[NSIndexPath indexPathForRow:newIndex++ inSection:0]]; 
       [*rowsDeleted addObject:[NSIndexPath indexPathForRow:oldIndex++ inSection:0]]; 
      } 
     } 
    } 
    } 
    // Once the loop is finished, add in what's left in the new array and remove what is left in the old array 
    for (; newIndex < newCount; ++newIndex) 
    [*rowsAdded addObject:[NSIndexPath indexPathForRow:newIndex inSection:0]]; 
    for (; oldIndex < oldCount; ++oldIndex) 
    [*rowsDeleted addObject:[NSIndexPath indexPathForRow:oldIndex inSection:0]]; 
} 

@end 

Entonces lo llaman así:

NSMutableArray *rowsAdded=nil, *rowsDeleted=nil; 
    [myArray computeDifferenceTo:newArray returningAdded:&rowsAdded andDeleted:&rowsDeleted]; 
    [myTableView beginUpdates]; 
    [myTableView insertRowsAtIndexPaths:rowsAdded withRowAnimation:UITableViewRowAnimationBottom]; 
    [myTableView deleteRowsAtIndexPaths:rowsDeleted withRowAnimation:UITableViewRowAnimationFade]; 
    [myTableView endUpdates]; 
Cuestiones relacionadas