2011-11-22 16 views
9

Ho una vista basata su NSTableView che talvolta filtro utilizzando NSPredicate. C'è un modo per animare gli elementi da rimuovere/aggiunti/riordinati in tutto il tableview per avere lo stesso effetto di beginUpdates, endUpdates e insertRowsAtIndexes:withAnimation, ecc.?Filtro NSTableView basato su visualizzazione + animazione

Ho esplorato modi come filtrare manualmente il mio array ma i miei tentativi si sono rivelati inutili, quindi ora mi chiedo se c'è un modo migliore (o integrato) per farlo. Mi sono chiesto se lo standard NSArrayController lo fa automaticamente, ma non penso che lo faccia.

+2

Non c'è niente di costruito in, temo - purtroppo. –

+0

NSCollectionView supporta questo out-of-the-box! – bijan

+0

La cosa più vicina che ho visto è per le tabelle basate su celle: http://www.mactech.com/articles/mactech/Vol.18/18.11/1811TableTechniques/index.html – sbooth

risposta

5

Ho scritto codice per farlo da solo - dati gli array "prima" e "dopo", calcola i parametri richiesti su insertRowsAtIndexPaths:, deleteRowsAtIndexPaths:, ecc. Il codice è un po 'approssimativo quindi probabilmente ha dei bug - usa a tua discrezione !

@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 

Poi si chiamano in questo modo:

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]; 
Problemi correlati