Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add customizable insert/delete animations #75

Merged
merged 6 commits into from
Apr 20, 2020

Conversation

bryankeller
Copy link
Contributor

@bryankeller bryankeller commented Apr 17, 2020

Details

This PR adds the ability to customize the animation used for newly inserted or deleted elements (items, section headers, section footers, and section backgrounds). The existing behavior was baked into MagazineLayout, and could not be customized. With the introduction of some new delegate functions, developers now have the opportunity to mutate layout attributes for inserted and deleted items.

By using default implementations for these new delegate functions, we're able to introduce this new functionality without changing existing animation behavior (a basic alpha fade for both inserts and deletes). This also enables us to introduce this new functionality without requiring any new API adoption.

Known issues:

  • Supplementary views don't animate in correctly (they appear immediately). This is potentially a collection view bug, or it might be something we can work around in a future patch. I need to compare with compositional layout to see if this is something we can fix.
  • Animations only occur if using performBatchUpdates. If a developer uses reloadData, the collection view doesn't bother do to any animations. This is expected behavior and will not be worked around or fixed.

Here's an example of customized delete animation:
ezgif com-video-to-gif-10

Related Issue

N/A

Motivation and Context

Currently, there is no way to customize insert / delete animations. Apps that want custom insert animations on page load, for example, need to be able to customize these animations.

How Has This Been Tested

Tested in the iOS simulator using custom insert and delete animations.

Types of changes

  • Docs change / refactoring / dependency upgrade
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.

@bryankeller bryankeller added the enhancement New feature or request label Apr 17, 2020
_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
initialLayoutAttributesForInsertedItemAt indexPath: IndexPath,
byModifying initialLayoutAttributes: UICollectionViewLayoutAttributes)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While it's a bit unconventional to pass in a reference and expect the delegate conformer to mutate it (is this done anywhere else in UIKit?), I think this API makes it pretty straightforward to do the right thing.

  • There's no return value, so there's nothing that would encourage an API implementer to make a copy of the layout attributes, modify that, and return that
  • The naming straight up tells you to modify the provided layout attributes (byModifying)
  • The documentation mentions, multiple times, that you should mutate the provided layout attributes directly, and also tells you what will happen if you don't modify the provided layout attributes

If somebody still manages to mess it up, then they don't deserve pretty animations 😆

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With all of that said, there's an alternative API:

API implementers could instead provide some struct that encapsulates all of the layout attributes properties, then internally in the layout, I'd apply these properties from the provided struct to the layout attributes.

Copy link
Contributor Author

@bryankeller bryankeller Apr 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Downsides to this API:

  • I need to make sure it's always kept up-to-date with whatever properties UICollectionViewLayoutAttributes has (in practice, that may equate to 0 effort)
  • I still need to pass something that represents the base layout attributes to the delegate function. If I pass an instance of UICollectionViewLayoutAttributes, then I'll need to make a copy of it that way if someone incorrectly decides to mutate it, it won't mess anything up internally in MagazineLayout

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While it's a bit unconventional to pass in a reference and expect the delegate conformer to mutate it (is this done anywhere else in UIKit?)

It's done here, which I guess is so that you can go with the system provided offset if you choose.

func scrollViewWillEndDragging(_ scrollView: UIScrollView, 
                           withVelocity velocity: CGPoint, 
                    targetContentOffset: UnsafeMutablePointer<CGPoint>)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that this current API is clear enough though, and doesn't have any significant drawbacks.

brynbodayle
brynbodayle previously approved these changes Apr 18, 2020
Copy link

@brynbodayle brynbodayle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Glad to have this, I've had some use cases for this in the past.

Copy link

@erichoracek erichoracek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great, thank you!

@bryankeller bryankeller merged commit 4a91fb2 into master Apr 20, 2020
@bryankeller bryankeller deleted the bk/add-customizable-animations branch April 20, 2020 20:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants