How to order moves, inserts, deletes, and updates in a UICollectionView performBatchUpdates block?










9














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.










share|improve this question




























    9














    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.










    share|improve this question


























      9












      9








      9


      2





      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.










      share|improve this question















      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






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited May 23 '17 at 12:33









      Community

      11




      11










      asked Jul 26 '16 at 18:55









      Brent Traut

      1,74532142




      1,74532142






















          2 Answers
          2






          active

          oldest

          votes


















          7














          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).






          share|improve this answer






















          • 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


















          2














          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.



          Collection View Updates Coalescing Slide






          share|improve this answer




















            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
            );



            );













            draft saved

            draft discarded


















            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









            7














            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).






            share|improve this answer






















            • 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















            7














            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).






            share|improve this answer






















            • 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













            7












            7








            7






            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).






            share|improve this answer














            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).







            share|improve this answer














            share|improve this answer



            share|improve this answer








            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
















            • 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













            2














            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.



            Collection View Updates Coalescing Slide






            share|improve this answer

























              2














              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.



              Collection View Updates Coalescing Slide






              share|improve this answer























                2












                2








                2






                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.



                Collection View Updates Coalescing Slide






                share|improve this answer












                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.



                Collection View Updates Coalescing Slide







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 12 '18 at 23:25









                Guillaume Algis

                7,85053261




                7,85053261



























                    draft saved

                    draft discarded
















































                    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.




                    draft saved


                    draft discarded














                    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





















































                    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







                    Popular posts from this blog

                    Top Tejano songwriter Luis Silva dead of heart attack at 64

                    ReactJS Fetched API data displays live - need Data displayed static

                    政党