Prevent the animated appearance of a UICollectionViewCell when presenting a UICollectionView

When the user performs some action, I need to pull the UICollectionView from the bottom to a certain height. Since this new state is completely optional, a collection view is created immediately before being presented in this way. Bottom-up animation is performed using changes to the NSLayoutConstraint constant property and calling [view layoutIfNeeded] in some animation block.

The problem is that by doing so, the cells become undesirable: they expand from the upper left corner to the specified size. I would like the collection view to appear and all its cells have already been laid out in their final size and appearance.

I know things like UIView setAnimationEnabled: but I cannot find how and where I should use this (if that is the case).

I suppose the problem is that collection view cells are added to the view hierarchy just before the animation block that contains the [superview layoutIfNeeded] call. This probably leads to the fact that UIKit believes that it should also animate these changes in the layout. If in this case the solution is likely to be something like an exception to the animation, then specific changes to the hierarchy of views.

+6
source share
2 answers

The extension in the upper left corner is usually a symptom of calling layoutIfNeeded in an animation block when the original view has never been laid out. You basically revive the initial layout, where all the subitems start with CGRectZero.

To solve it, you will need two things:

  • Make sure that the restriction you are editing is related to the viewing position of the collection, not the size. By this, I mean that you can’t imagine your view of the collection by changing its height from zero to the final value.
  • Call layoutIfNeeded in your view before editing the constraint, and then call it again in the animation block after you make this change. This way you only animate the change you specify for the constraint, not the entire layout.
+10
source

I have been dealing with this problem for about 3 days and finally got a solution. I just added an animation block that gets called after a very small timer

 UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 7 , options: .CurveEaseInOut, animations: { self.view.layoutIfNeeded() }){ _ in} 

will be

 let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC))) dispatch_after(delayTime, dispatch_get_main_queue()) { self.changeConstraint() } private func changeConstraint(){ UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 7 , options: .CurveEaseInOut, animations: { self.view.layoutIfNeeded() }){ _ in} } 

See the magic :)

0
source

Source: https://habr.com/ru/post/948010/


All Articles