2013-05-24 10 views
5

Mam problemy z animowaniem zmian między sekcjami w UICollectionView, mój program ulega awarii, co jest z nim nie tak?UICollectionView ulega awarii podczas zmiany kolejności elementów między sekcjami

Mam Zobacz kolekcję, która ma cztery sekcje:

0: A
1: B
2: C
3: D

Chcę przekształcić go mieć tylko trzy sekcje z tych samych przedmiotów:

0: A
1: B, C
2: D

I chcę, aby animować tej transformacji :

// Initial state 

NSArray *source = @[ @[@"A"], @[@"B"], @[@"C"], @[@"D"] ]; 


// Some data source methods 

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 
{ 
    return [source[section] count]; 
} 

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView 
{ 
    return [source count]; 
} 


// Transformation: that works but I have to keep an empty section 

source = @[ @[@"A"], @[@"B", @"C"], @[@"D"], @[] ]; 

[collection performBatchUpdates:^{ 
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] 
         toIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]]; 
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:1] 
         toIndexPath:[NSIndexPath indexPathForItem:0 inSection:1]]; 
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:2] 
         toIndexPath:[NSIndexPath indexPathForItem:1 inSection:1]]; 
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:3] 
         toIndexPath:[NSIndexPath indexPathForItem:0 inSection:2]]; 
} completion:nil]; 


// Transformation: that crashes! 

source = @[ @[@"A"], @[@"B", @"C"], @[@"D"] ]; 

[collection performBatchUpdates:^{ 
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] 
         toIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]]; 
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:1] 
         toIndexPath:[NSIndexPath indexPathForItem:0 inSection:1]]; 
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:2] 
         toIndexPath:[NSIndexPath indexPathForItem:1 inSection:1]]; 
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:3] 
         toIndexPath:[NSIndexPath indexPathForItem:0 inSection:2]]; 
    [collection deleteSections:[NSIndexSet indexSetWithIndex:3]]; 
} completion:nil]; 

Ciągle pojawiają się awarie, albo wewnętrzne niepowodzenie asercji: Assertion failure in -[UICollectionView _endItemAnimations]..., a czasami jeszcze bardziej dziwny błąd malloc: incorrect checksum for freed object....

Jeśli nie zadzwonię pod numer deleteSections:, to również nie działa. Jeśli postawię pierwszy, to nic nie zmieni. Jeśli usuniemy moveItemAtIndexPath:toIndexPath:, które mają to samo źródło i miejsce docelowe, nic nie zmieni. Jeśli nie zrobię tego w bloku wsadowym, to oczywiście ulega awarii przy pierwszym poleceniu. Czy przeoczyłem coś?

+0

czy kiedykolwiek znalazłeś na to rozwiązanie? Wydaje się, że użycie moveItemAtIndexPath: toIndexPath: i deleteSections: w tej samej aktualizacji partii zawsze prowadzi do awarii, ale chciałby potwierdzenia. –

Odpowiedz

0

Próbowałeś coś takiego:

source = @[ @[@"A"], @[@"B", @"C"], @[@"D"] ]; 

[collection performBatchUpdates:^{ 
    [collection moveItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:2] 
         toIndexPath:[NSIndexPath indexPathForItem:1 inSection:1]]; 
    [collection deleteSections:[NSIndexSet indexSetWithIndex:2]]; 
} completion:nil]; 
+0

Właściwie uważam, że problem polega na tym, że nie możemy mieszać aktualizacji sekcji i produktów, które mogą powodować konflikt. Jeśli usuniemy sekcję 2, oznacza to, że usuniemy również elementy zawarte w sekcji 2, ale już wcześniej poprosiliśmy o przeniesienie elementu w sekcji 2, więc nie możemy jednocześnie przenieść i usunąć pozycji ... Czuję, że jedynym rozwiązaniem jest utrzymanie stałej liczby sekcji. – Guillaume

1

wyciąg z tej bardzo interesującej article o UICollectionView:

When inserting a new section within the batch update block, one must not insert any items into that section – that will be handled implicitly. In fact, inserting items into a newly-inserted section in a batch update block creates “ghost” layers which get stuck in the collection view layer hierarchy. Presumably this is a just bug with UICollectionView, as this behavior is not documented and no exception is thrown

Wiedząc o tym, uważam, że nie dziwi wcale, że usunięcie sekcji i moveItemFromIndexPath:toIndexPath nie działają też dobrze razem. Myślę, że to "rodzaj tego samego błędu".

Rozwiązanie użyłem:

umieścić fałszywy niewidzialną komórkę w sekcji Powinienem był usunięty. To pozwoliło mi zachować takie samo zachowanie, jak gdybym zrobił moveItemFromIndexPath:toIndexPath:. Oczywiście odpowiednio dostosowałem swój zasób danych!