How to order moves, inserts, deletes, and updates in a UICollectionView performBatchUpdates block?
In my UICollectionView
, I use a simple array of custom objects to produce and display cells. Occasionally that data changes and I'd like to animate the changes all at once. I've chosen to do this by tracking all the changes in a second array, diff'ing the two, and producing a set of move, insert, delete, and update operations inside of a performBatchUpdates
block. I now realize it's pretty tricky to do all of these inside the same block because you have to worry about orders of operations with indexes. In fact, the accepted answer to this issue is wrong (but corrected in the comments).
The documentation seems pretty lacking, but it covers one case:
Deletes are processed before inserts in batch operations. This means
the indexes for the deletions are processed relative to the indexes of
the collection view’s state before the batch operation, and the
indexes for the insertions are processed relative to the indexes of
the state after all the deletions in the batch operation.
However, the document doesn't talk about when moves are processed. If I call moveItemAtIndexPath
and deleteItemsAtIndexPaths
in the same performBatchUpdates
, should the move indexes be relative to the pre- or post-deleted order? How about insertItemsAtIndexPaths
?
Finally, I'm facing issues calling reloadItemsAtIndexPaths
and moveItemAtIndexPath
in the same operation:
Fatal Exception: NSInternalInconsistencyException attempt to delete
and reload the same index path
Is there a way to do all the operations I want in the same performBatchUpdates
? If so, what order do the updates get processed relative to the others? If not, what do people usually do? Reload the data after doing all other operations? Before? I'd much prefer if all the animations happened in a single stage.
ios objective-c swift uicollectionview uikit
add a comment |
In my UICollectionView
, I use a simple array of custom objects to produce and display cells. Occasionally that data changes and I'd like to animate the changes all at once. I've chosen to do this by tracking all the changes in a second array, diff'ing the two, and producing a set of move, insert, delete, and update operations inside of a performBatchUpdates
block. I now realize it's pretty tricky to do all of these inside the same block because you have to worry about orders of operations with indexes. In fact, the accepted answer to this issue is wrong (but corrected in the comments).
The documentation seems pretty lacking, but it covers one case:
Deletes are processed before inserts in batch operations. This means
the indexes for the deletions are processed relative to the indexes of
the collection view’s state before the batch operation, and the
indexes for the insertions are processed relative to the indexes of
the state after all the deletions in the batch operation.
However, the document doesn't talk about when moves are processed. If I call moveItemAtIndexPath
and deleteItemsAtIndexPaths
in the same performBatchUpdates
, should the move indexes be relative to the pre- or post-deleted order? How about insertItemsAtIndexPaths
?
Finally, I'm facing issues calling reloadItemsAtIndexPaths
and moveItemAtIndexPath
in the same operation:
Fatal Exception: NSInternalInconsistencyException attempt to delete
and reload the same index path
Is there a way to do all the operations I want in the same performBatchUpdates
? If so, what order do the updates get processed relative to the others? If not, what do people usually do? Reload the data after doing all other operations? Before? I'd much prefer if all the animations happened in a single stage.
ios objective-c swift uicollectionview uikit
add a comment |
In my UICollectionView
, I use a simple array of custom objects to produce and display cells. Occasionally that data changes and I'd like to animate the changes all at once. I've chosen to do this by tracking all the changes in a second array, diff'ing the two, and producing a set of move, insert, delete, and update operations inside of a performBatchUpdates
block. I now realize it's pretty tricky to do all of these inside the same block because you have to worry about orders of operations with indexes. In fact, the accepted answer to this issue is wrong (but corrected in the comments).
The documentation seems pretty lacking, but it covers one case:
Deletes are processed before inserts in batch operations. This means
the indexes for the deletions are processed relative to the indexes of
the collection view’s state before the batch operation, and the
indexes for the insertions are processed relative to the indexes of
the state after all the deletions in the batch operation.
However, the document doesn't talk about when moves are processed. If I call moveItemAtIndexPath
and deleteItemsAtIndexPaths
in the same performBatchUpdates
, should the move indexes be relative to the pre- or post-deleted order? How about insertItemsAtIndexPaths
?
Finally, I'm facing issues calling reloadItemsAtIndexPaths
and moveItemAtIndexPath
in the same operation:
Fatal Exception: NSInternalInconsistencyException attempt to delete
and reload the same index path
Is there a way to do all the operations I want in the same performBatchUpdates
? If so, what order do the updates get processed relative to the others? If not, what do people usually do? Reload the data after doing all other operations? Before? I'd much prefer if all the animations happened in a single stage.
ios objective-c swift uicollectionview uikit
In my UICollectionView
, I use a simple array of custom objects to produce and display cells. Occasionally that data changes and I'd like to animate the changes all at once. I've chosen to do this by tracking all the changes in a second array, diff'ing the two, and producing a set of move, insert, delete, and update operations inside of a performBatchUpdates
block. I now realize it's pretty tricky to do all of these inside the same block because you have to worry about orders of operations with indexes. In fact, the accepted answer to this issue is wrong (but corrected in the comments).
The documentation seems pretty lacking, but it covers one case:
Deletes are processed before inserts in batch operations. This means
the indexes for the deletions are processed relative to the indexes of
the collection view’s state before the batch operation, and the
indexes for the insertions are processed relative to the indexes of
the state after all the deletions in the batch operation.
However, the document doesn't talk about when moves are processed. If I call moveItemAtIndexPath
and deleteItemsAtIndexPaths
in the same performBatchUpdates
, should the move indexes be relative to the pre- or post-deleted order? How about insertItemsAtIndexPaths
?
Finally, I'm facing issues calling reloadItemsAtIndexPaths
and moveItemAtIndexPath
in the same operation:
Fatal Exception: NSInternalInconsistencyException attempt to delete
and reload the same index path
Is there a way to do all the operations I want in the same performBatchUpdates
? If so, what order do the updates get processed relative to the others? If not, what do people usually do? Reload the data after doing all other operations? Before? I'd much prefer if all the animations happened in a single stage.
ios objective-c swift uicollectionview uikit
ios objective-c swift uicollectionview uikit
edited May 23 '17 at 12:33
Community♦
11
11
asked Jul 26 '16 at 18:55
Brent Traut
1,74532142
1,74532142
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
For the move operations, the from indexPath is pre-delete indices, and the to indexPath is post-delete indices. Reloads should only be specified for indexPaths that have not been inserted, deleted, or moved. This is probably why you're seeing the NSInternalInconsistencyException
.
A handy way to verify the operations are set up correctly: the set of reload, insert and move-to indexPaths should not have any duplicates, and the set of reload, delete, and move-from indexPaths should not have any duplicates.
UPDATE:
It appears that items that you move are not also updated, but only moved. So, if you need to update and move an item, you can perform the reload before or after the batch update (depending on the state of your data source).
So let's say I have a cell that needs updating because it'll be displayed different (different color, for example), and I also need to move it. This is an example of where I need to move and reload. Is there any way to do these in the same animation block?
– Brent Traut
Jul 28 '16 at 7:17
Because you're doing the move, the cell will automatically reload. You don't need to explicitly reload it.
– Mark
Jul 28 '16 at 12:09
Oh! I didn't realize (and I guess I failed to experiment this case). I assumed it would just move the content containers without reloading them.
– Brent Traut
Jul 28 '16 at 18:45
1
Are moves before or after inserts? Or is a move the same as a delete plus an insert in terms of indexing?
– sudo
Oct 12 '17 at 6:10
1
The latter. To figure out your move indexes, pretend it’s a delete and an insert.
– Mark
Oct 12 '17 at 12:25
|
show 1 more comment
Mark's answer is right. I'd recommend watching WWDC's 2018 Session 225 "A Tour of UICollectionView" to get the full explanation from an Apple engineer.
You can skip to the 33'36" mark for the interesting bit.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f38597804%2fhow-to-order-moves-inserts-deletes-and-updates-in-a-uicollectionview-performb%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
For the move operations, the from indexPath is pre-delete indices, and the to indexPath is post-delete indices. Reloads should only be specified for indexPaths that have not been inserted, deleted, or moved. This is probably why you're seeing the NSInternalInconsistencyException
.
A handy way to verify the operations are set up correctly: the set of reload, insert and move-to indexPaths should not have any duplicates, and the set of reload, delete, and move-from indexPaths should not have any duplicates.
UPDATE:
It appears that items that you move are not also updated, but only moved. So, if you need to update and move an item, you can perform the reload before or after the batch update (depending on the state of your data source).
So let's say I have a cell that needs updating because it'll be displayed different (different color, for example), and I also need to move it. This is an example of where I need to move and reload. Is there any way to do these in the same animation block?
– Brent Traut
Jul 28 '16 at 7:17
Because you're doing the move, the cell will automatically reload. You don't need to explicitly reload it.
– Mark
Jul 28 '16 at 12:09
Oh! I didn't realize (and I guess I failed to experiment this case). I assumed it would just move the content containers without reloading them.
– Brent Traut
Jul 28 '16 at 18:45
1
Are moves before or after inserts? Or is a move the same as a delete plus an insert in terms of indexing?
– sudo
Oct 12 '17 at 6:10
1
The latter. To figure out your move indexes, pretend it’s a delete and an insert.
– Mark
Oct 12 '17 at 12:25
|
show 1 more comment
For the move operations, the from indexPath is pre-delete indices, and the to indexPath is post-delete indices. Reloads should only be specified for indexPaths that have not been inserted, deleted, or moved. This is probably why you're seeing the NSInternalInconsistencyException
.
A handy way to verify the operations are set up correctly: the set of reload, insert and move-to indexPaths should not have any duplicates, and the set of reload, delete, and move-from indexPaths should not have any duplicates.
UPDATE:
It appears that items that you move are not also updated, but only moved. So, if you need to update and move an item, you can perform the reload before or after the batch update (depending on the state of your data source).
So let's say I have a cell that needs updating because it'll be displayed different (different color, for example), and I also need to move it. This is an example of where I need to move and reload. Is there any way to do these in the same animation block?
– Brent Traut
Jul 28 '16 at 7:17
Because you're doing the move, the cell will automatically reload. You don't need to explicitly reload it.
– Mark
Jul 28 '16 at 12:09
Oh! I didn't realize (and I guess I failed to experiment this case). I assumed it would just move the content containers without reloading them.
– Brent Traut
Jul 28 '16 at 18:45
1
Are moves before or after inserts? Or is a move the same as a delete plus an insert in terms of indexing?
– sudo
Oct 12 '17 at 6:10
1
The latter. To figure out your move indexes, pretend it’s a delete and an insert.
– Mark
Oct 12 '17 at 12:25
|
show 1 more comment
For the move operations, the from indexPath is pre-delete indices, and the to indexPath is post-delete indices. Reloads should only be specified for indexPaths that have not been inserted, deleted, or moved. This is probably why you're seeing the NSInternalInconsistencyException
.
A handy way to verify the operations are set up correctly: the set of reload, insert and move-to indexPaths should not have any duplicates, and the set of reload, delete, and move-from indexPaths should not have any duplicates.
UPDATE:
It appears that items that you move are not also updated, but only moved. So, if you need to update and move an item, you can perform the reload before or after the batch update (depending on the state of your data source).
For the move operations, the from indexPath is pre-delete indices, and the to indexPath is post-delete indices. Reloads should only be specified for indexPaths that have not been inserted, deleted, or moved. This is probably why you're seeing the NSInternalInconsistencyException
.
A handy way to verify the operations are set up correctly: the set of reload, insert and move-to indexPaths should not have any duplicates, and the set of reload, delete, and move-from indexPaths should not have any duplicates.
UPDATE:
It appears that items that you move are not also updated, but only moved. So, if you need to update and move an item, you can perform the reload before or after the batch update (depending on the state of your data source).
edited Aug 27 '16 at 16:35
answered Jul 28 '16 at 1:50
Mark
5,27233151
5,27233151
So let's say I have a cell that needs updating because it'll be displayed different (different color, for example), and I also need to move it. This is an example of where I need to move and reload. Is there any way to do these in the same animation block?
– Brent Traut
Jul 28 '16 at 7:17
Because you're doing the move, the cell will automatically reload. You don't need to explicitly reload it.
– Mark
Jul 28 '16 at 12:09
Oh! I didn't realize (and I guess I failed to experiment this case). I assumed it would just move the content containers without reloading them.
– Brent Traut
Jul 28 '16 at 18:45
1
Are moves before or after inserts? Or is a move the same as a delete plus an insert in terms of indexing?
– sudo
Oct 12 '17 at 6:10
1
The latter. To figure out your move indexes, pretend it’s a delete and an insert.
– Mark
Oct 12 '17 at 12:25
|
show 1 more comment
So let's say I have a cell that needs updating because it'll be displayed different (different color, for example), and I also need to move it. This is an example of where I need to move and reload. Is there any way to do these in the same animation block?
– Brent Traut
Jul 28 '16 at 7:17
Because you're doing the move, the cell will automatically reload. You don't need to explicitly reload it.
– Mark
Jul 28 '16 at 12:09
Oh! I didn't realize (and I guess I failed to experiment this case). I assumed it would just move the content containers without reloading them.
– Brent Traut
Jul 28 '16 at 18:45
1
Are moves before or after inserts? Or is a move the same as a delete plus an insert in terms of indexing?
– sudo
Oct 12 '17 at 6:10
1
The latter. To figure out your move indexes, pretend it’s a delete and an insert.
– Mark
Oct 12 '17 at 12:25
So let's say I have a cell that needs updating because it'll be displayed different (different color, for example), and I also need to move it. This is an example of where I need to move and reload. Is there any way to do these in the same animation block?
– Brent Traut
Jul 28 '16 at 7:17
So let's say I have a cell that needs updating because it'll be displayed different (different color, for example), and I also need to move it. This is an example of where I need to move and reload. Is there any way to do these in the same animation block?
– Brent Traut
Jul 28 '16 at 7:17
Because you're doing the move, the cell will automatically reload. You don't need to explicitly reload it.
– Mark
Jul 28 '16 at 12:09
Because you're doing the move, the cell will automatically reload. You don't need to explicitly reload it.
– Mark
Jul 28 '16 at 12:09
Oh! I didn't realize (and I guess I failed to experiment this case). I assumed it would just move the content containers without reloading them.
– Brent Traut
Jul 28 '16 at 18:45
Oh! I didn't realize (and I guess I failed to experiment this case). I assumed it would just move the content containers without reloading them.
– Brent Traut
Jul 28 '16 at 18:45
1
1
Are moves before or after inserts? Or is a move the same as a delete plus an insert in terms of indexing?
– sudo
Oct 12 '17 at 6:10
Are moves before or after inserts? Or is a move the same as a delete plus an insert in terms of indexing?
– sudo
Oct 12 '17 at 6:10
1
1
The latter. To figure out your move indexes, pretend it’s a delete and an insert.
– Mark
Oct 12 '17 at 12:25
The latter. To figure out your move indexes, pretend it’s a delete and an insert.
– Mark
Oct 12 '17 at 12:25
|
show 1 more comment
Mark's answer is right. I'd recommend watching WWDC's 2018 Session 225 "A Tour of UICollectionView" to get the full explanation from an Apple engineer.
You can skip to the 33'36" mark for the interesting bit.
add a comment |
Mark's answer is right. I'd recommend watching WWDC's 2018 Session 225 "A Tour of UICollectionView" to get the full explanation from an Apple engineer.
You can skip to the 33'36" mark for the interesting bit.
add a comment |
Mark's answer is right. I'd recommend watching WWDC's 2018 Session 225 "A Tour of UICollectionView" to get the full explanation from an Apple engineer.
You can skip to the 33'36" mark for the interesting bit.
Mark's answer is right. I'd recommend watching WWDC's 2018 Session 225 "A Tour of UICollectionView" to get the full explanation from an Apple engineer.
You can skip to the 33'36" mark for the interesting bit.
answered Nov 12 '18 at 23:25
Guillaume Algis
7,85053261
7,85053261
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f38597804%2fhow-to-order-moves-inserts-deletes-and-updates-in-a-uicollectionview-performb%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown