Hi Im trying to add an observer for my model to notify UITableview about any changes in the model. with this pattern I can decouple the model and view and I can put UITableViewDataSource in another class.
until now everything works well. but the problem is that when I inserting more than one object in the tableView the first row insert animation doesn't work.
it only happens for UITableViewRowAnimationTop. and I have tested on the real device. but no hope!
does anyone have any idea how can I fix this?
here is the code:
- (void)viewDidLoad
{
[super viewDidLoad];
Item *item = [Item new];
item.name = @"Computer";
Item *item2 = [Item new];
item2.name = @"lapTop";
item2.parent = item;
Item *item3 = [Item new];
item3.name = @"NoteBook";
item3.parent = item;
item.children = [NSSet setWithObjects:item2,item3, nil];
self.Items = [NSMutableArray arrayWithObject:item];
[self addObserver:self
forKeyPath:@"items"
options:0
context:NULL];
}
#pragma mark - Table View Data Source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.Items.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
Item *object =(Item *)[self.Items objectAtIndex: indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
NSLog(@"%@",object.name);
if (object.parent != NULL) {
cell.indentationLevel = 1;
cell.indentationWidth = 25;
}
cell.textLabel.text = object.name;
return cell;
}
#pragma mark - Table View Delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *dic=[self.Items objectAtIndex:indexPath.row];
if([dic valueForKey:@"children"])
{
NSArray *children=[dic valueForKey:@"children"];
BOOL isTableExpanded=NO;
for(Item *child in children )
{
NSInteger index=[self.Items indexOfObjectIdenticalTo:child];
isTableExpanded=(index>0 && index!=NSIntegerMax);
if(isTableExpanded) break;
}
if(isTableExpanded)
{
[self CollapseRows:children];
}
else
{
NSUInteger count=indexPath.row+1;
NSMutableArray *arrCells=[NSMutableArray array];
for(Item *subItem in children )
{
NSLog(@"%@",subItem.name);
if (subItem.parent != NULL) {
[arrCells addObject:[NSIndexPath indexPathForRow:count inSection:0]];
[self insertObject:subItem inItemsAtIndex:count++];
}
}
//[self.tableView insertRowsAtIndexPaths:arrCells withRowAnimation:UITableViewRowAnimationTop];
}
}
}
-(void)CollapseRows:(NSArray*)ar
{
for(NSDictionary *dInner in ar )
{
NSUInteger indexToRemove=[self.Items indexOfObjectIdenticalTo:dInner];
NSArray *arInner=[dInner valueForKey:@"children"];
if(arInner && [arInner count]>0)
{
[self CollapseRows:arInner];
}
if([self.Items indexOfObjectIdenticalTo:dInner]!=NSNotFound)
{
[self removeObjectFromItemsAtIndex:[self.Items indexOfObjectIdenticalTo:dInner]];
// [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:
// [NSIndexPath indexPathForRow:indexToRemove inSection:0]
// ]
// withRowAnimation:UITableViewRowAnimationTop];
}
}
}
#pragma mark KVO
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
NSIndexSet *indices = [change objectForKey:NSKeyValueChangeIndexesKey];
if (indices == nil)
return; // Nothing to do
// Build index paths from index sets
NSUInteger indexCount = [indices count];
NSUInteger buffer[indexCount];
[indices getIndexes:buffer maxCount:indexCount inIndexRange:nil];
NSMutableArray *indexPathArray = [NSMutableArray array];
for (int i = 0; i < indexCount; i++) {
NSUInteger indexPathIndices[2];
indexPathIndices[0] = 0;
indexPathIndices[1] = buffer[i];
NSIndexPath *newPath = [NSIndexPath indexPathWithIndexes:indexPathIndices length:2];
[indexPathArray addObject:newPath];
}
NSNumber *kind = [change objectForKey:NSKeyValueChangeKindKey];
if ([kind integerValue] == NSKeyValueChangeInsertion) // Rows were added
[self.tableView insertRowsAtIndexPaths:indexPathArray withRowAnimation:UITableViewRowAnimationTop];
else if ([kind integerValue] == NSKeyValueChangeRemoval) // Rows were removed
[self.tableView deleteRowsAtIndexPaths:indexPathArray withRowAnimation:UITableViewRowAnimationTop];
}
#pragma mark Array Accessors
- (NSUInteger)countOfItems
{
return [self.Items count];
}
- (id)objectInItemsAtIndex:(NSUInteger)idx
{
return [self.Items objectAtIndex:idx];
}
- (void)insertObject:(id)anObject inItemsAtIndex:(NSUInteger)idx
{
//[self willChangeValueForKey:@"menus"];
[self.Items insertObject:anObject atIndex:idx];
}
- (void)removeObjectFromItemsAtIndex:(NSUInteger)idx
{
[self.Items removeObjectAtIndex:idx];
}