2011-11-22 5 views
9

私は時々NSPredicateを使ってフィルタリングするビューベースのNSTableViewを持っています。 tableview全体で、削除/追加/並べ替え中のアイテムにアニメーションを付ける方法はありますか?beginUpdates,endUpdatesinsertRowsAtIndexes:withAnimationなどと同じ効果がありますか?ビューベースのNSTableViewフィルタリング+アニメーション

私はアレイを手作業でフィルタリングするなどの方法を模索しましたが、私の試みは無駄であることが判明しましたので、これを行うにはより良い(または組み込みの方法)があるのだろうかと思います。私はNSArrayControllerがこれを自動的に行うのかどうか疑問に思っていますが、私はそうは思わない。

+2

で構築されたものは何もありません、私は怖い - 残念なことに。 –

+0

NSCollectionViewは、このアウトオブボックスをサポートしています! – bijan

+0

私が見たもっとも近いものは、セルベースのテーブルです:http://www.mactech.com/articles/mactech/Vol.18/18.11/1811TableTechniques/index.html – sbooth

答えて

5

「before」と「after」の配列を指定して、必要なパラメータをinsertRowsAtIndexPaths:,deleteRowsAtIndexPaths:などと計算するコードを書いています。このコードはちょっと混乱しているかもしれません。あなたの裁量で使用してください!

@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 

は、その後、あなたはこのようにそれを呼び出す:

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]; 
関連する問題