问题
I am starting out using key value observing, and the mutable array I'm observing gives me NSIndexSets (Ordered mutable to-many) in the change dictionary. The problem is the table view as far as I know wants me to give it NSArrays full of indexes.
I thought about implementing a custom method to translate one to the other, but this seems slow and I get the impression there must be a better way to make this table view update when the array changes.
This is the method from my UITableViewDataSource.
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
switch ([[change valueForKey:NSKeyValueChangeKindKey] unsignedIntValue]) {
case NSKeyValueChangeSetting:
NSLog(@"Setting Change");
break;
case NSKeyValueChangeInsertion:
NSLog(@"Insertion Change");
// How do I fit this:
NSIndexSet * indexes = [change objectForKey:NSKeyValueChangeIndexesKey];
// into this:
[self.tableView insertRowsAtIndexPaths:<#(NSArray *)#> withRowAnimation:<#(UITableViewRowAnimation)#>
// Or am I just doing it wrong?
break;
case NSKeyValueChangeRemoval:
NSLog(@"Removal Change");
break;
case NSKeyValueChangeReplacement:
NSLog(@"Replacement Change");
break;
default:
break;
}
}
回答1:
This seems easy enough. Enumerate the index set using enumerateIndexesUsingBlock: and stick each index into an NSIndexPath object:
NSMutableArray * paths = [NSMutableArray array];
[indexes enumerateIndexesUsingBlock:^(NSUInteger index, BOOL *stop) {
[paths addObject:[NSIndexPath indexPathWithIndex:index]];
}];
[self.tableView insertRowsAtIndexPaths:paths
withRowAnimation:<#(UITableViewRowAnimation)#>];
If your table view has sections, it's only a bit more complicated, because you'll need to get the correct section number, and specify it in the index path:
NSUInteger sectionAndRow[2] = {sectionNumber, index};
[NSIndexPath indexPathWithIndexes:sectionAndRow
length:2];
回答2:
Here's a category for NSIndexSet:
@interface NSIndexSet (mxcl)
- (NSArray *)indexPaths;
@end
@implementation NSIndexSet (mxcl)
- (NSArray *)indexPaths {
NSUInteger rows[self.count];
[self getIndexes:rows maxCount:self.count inIndexRange:NULL];
NSIndexPath *paths[self.count];
for (int x = 0; x < self.count; ++x)
paths[x] = [NSIndexPath indexPathForRow:rows[x] inSection:0];
return [NSArray arrayWithObjects:paths count:self.count];
}
@end
Code would be shorter with an NSMutableArray, but something in me tries to resist making mutable objects when the result is intended to be constant.
来源:https://stackoverflow.com/questions/6237311/how-should-i-handle-the-nsindexset-from-kvo-to-update-a-table-view