Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Limiting vertical movement of UIAttachmentBehavior inside a UICollectionView

I have a horizontal UICollectionView with a custom UICollectionViewFlowLayout that has a UIAttachmentBehavior set on each cell to give it a bouncy feel when scrolling left and right. The behavior has the following properties:

attachmentBehavior.length = 1.0f;
attachmentBehavior.damping = 0.5f;
attachmentBehavior.frequency = 1.9f;

When a new cell is added to the collection view it's added at the bottom and then animated to its position also using a UIAttachmentBehavior. Naturally it bounces up and down a bit till it rests in its position. Everything is working as expected till now.

enter image description here

The problem I have starts appearing when the collection view is scrolled left or right before the newly added cell has come to rest. The adds left and right bounciness to the up and down one the cell already has from being added. This results in a very weird circular motion in the cell.

enter image description here

My question is, is it possible to stop the vertical motion of a UIAttachmentBehavior while the collection view is being scrolled? I've tried different approaches like using multiple attachment behaviors and disabling scrolling in the collection view till the newly added cell has come to rest, but non of them seem to stop this.

like image 292
Hesham Avatar asked May 05 '14 17:05

Hesham


3 Answers

One way to solve this is to use the inherited .action property of the attachment behavior.

You will need to set up a couple of variables first, something like (going from memory, untested code):

BOOL limitVerticalMovement = TRUE;
CGFloat staticCenterY = CGRectGetHeight(self.collectionView.frame) / 2;

Set these as properties of your custom UICollectionViewFlowLayout

When you create your attachment behavior:

UIAttachmentBehavior *attachment = [[UIAttachmentBehavior alloc] initWithItem:item attachedToAnchor:center];
attachment.damping = 1.0f;
attachment.frequency = 1.5f;
attachment.action = ^{
    if (!limitVerticalMovement) return;

    CGPoint center = item.center;
    center.y = staticCenterY;
    item.center = center;
};

Then you can turn the limiting function on and off by setting limitVerticalMovement as appropriate.

like image 189
Erwin Avatar answered Oct 14 '22 06:10

Erwin


If you're using iOS 9 and above then sliding function within attachment class will work perfectly for that job:

class func slidingAttachmentWithItem(_ item: UIDynamicItem,
                attachmentAnchor point: CGPoint,
               axisOfTranslation axis: CGVector) -> Self

it can be used easily, and it's very effective for sliding Apple documentation

like image 37
Abdoelrhman Avatar answered Oct 14 '22 08:10

Abdoelrhman


Have you tried manually removing animations from cells with CALayer's removeAllAnimations?

like image 29
Rivera Avatar answered Oct 14 '22 08:10

Rivera