2011-11-22 31 views
9

Tôi có chế độ xem dựa trên NSTableView mà đôi khi tôi lọc sử dụng NSPredicate. Có cách nào để tạo hoạt ảnh cho các mục bị xóa/thêm/sắp xếp lại trong suốt tableview để có cùng tác dụng như beginUpdates, endUpdatesinsertRowsAtIndexes:withAnimation, v.v. không?Bộ lọc NSTableView dựa trên chế độ xem + hoạt ảnh

Tôi đã khám phá các cách như lọc theo cách thủ công mảng của mình nhưng nỗ lực của tôi được chứng minh là vô ích vì vậy bây giờ tôi tự hỏi nếu có cách nào tốt hơn (hoặc được xây dựng) để thực hiện việc này. Tôi đã tự hỏi nếu NSArrayController thực hiện điều này tự động nhưng tôi không nghĩ điều đó xảy ra.

+2

Không có gì được xây dựng trong, tôi sợ là - không may. –

+0

NSCollectionView hỗ trợ tính năng out-of-the-box này! – bijan

+0

Điều gần nhất tôi thấy là dành cho các bảng dựa trên ô: http://www.mactech.com/articles/mactech/Vol.18/18.11/1811TableTechniques/index.html – sbooth

Trả lời

5

Tôi đã viết mã để tự làm điều này - đưa ra các tham số 'trước' và 'sau', tính toán các tham số cần thiết thành insertRowsAtIndexPaths:, deleteRowsAtIndexPaths:, v.v. Mã hơi khó sử dụng nên có thể có lỗi - sử dụng theo quyết định của bạ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 

Sau đó, bạn gọi nó là như thế này:

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]; 
Các vấn đề liên quan