限制UIAttachmentBehavior在UICollectionView内的垂直移动

时间:2014-05-05 17:23:07

标签: ios objective-c uicollectionview uikit-dynamics

我有一个水平UICollectionView,其自定义UICollectionViewFlowLayout在每个单元格上设置UIAttachmentBehavior,以便在向左和向右滚动时赋予其弹性感。该行为具有以下属性:

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

当新的单元格添加到集合视图时,它会添加到底部,然后使用UIAttachmentBehavior设置动画到其位置。当然它会一点一点地反弹,直到它停留在它的位置上。到目前为止,一切都按预期工作。

enter image description here

在新添加的单元格停止之前向左或向右滚动集合视图时,我出现的问题开始出现。这增加了单元格已经具有的向上和向下的左右弹性。这导致细胞中非常奇怪的圆周运动。

enter image description here

我的问题是,是否可以在滚动集合视图时停止UIAttachmentBehavior的垂直运动?我尝试了不同的方法,比如使用多个附件行为并在集合视图中禁用滚动,直到新添加的单元格停止,但是没有它们似乎停止了这一点。

6 个答案:

答案 0 :(得分:3)

解决此问题的一种方法是使用附件行为的继承.action属性。

首先需要设置几个变量,例如(从内存中获取,未经测试的代码):

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

将这些设置为自定义UICollectionViewFlowLayout

的属性

创建附件行为时:

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

然后您可以根据需要设置limitVerticalMovement来打开和关闭限制功能。

答案 1 :(得分:2)

如果你正在使用iOS 9及更高版本,那么附件类中的滑动功能将完全适用于该作业:

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

它可以轻松使用,并且对滑动非常有效[Apple文档] 1

答案 2 :(得分:1)

您是否尝试使用CALayer的{​​{1}}手动删除动画?

答案 3 :(得分:1)

您希望在集合视图开始滚动时删除该行为,或者可能会大大减少弹性,以便它能够平稳地,但很快地恢复。如果你仔细想想,你所看到的是你所描述的依恋行为的现实运动。

为了使垂直弹跳保持相同的速率但防止水平弹跳,您需要添加其他行为 - 例如与每个添加的单元格的左侧和右侧的边界的碰撞行为。这会稍微增加物理的复杂性,并可能影响滚动性能,但值得一试。

答案 4 :(得分:1)

以下是我设法做到的方法。 FloatRange限制了附件的范围,因此如果您希望它一直在屏幕上下移动,您只需设置非常大的数字。

这里面是func recognitionPanGesture(发件人:UIPanGestureRecognizer){}

let location = sender.location(in: yourView.superview)
var direction = "Y"

var center = CGPoint(x: 0, y: 0)
if self.direction == "Y" {center.y = 1}
if self.direction == "X" {center.x = 1}

let sliding = UIAttachmentBehavior.slidingAttachment(with: youView, attachmentAnchor: location, axisOfTranslation: CGVector(dx: center.x, dy: center.y))

sliding.attachmentRange = UIFloatRange(minimum: -2000, maximum: 2000)
animator = UIDynamicAnimator(referenceView: self.superview!)
animator.addBehavior(sliding)

答案 5 :(得分:0)

我已经在添加新单元格后的特定时间内在集合视图中禁用滚动,然后使用其action属性删除附件行为,然后添加立即再次出现新的依恋行为。

这样我确保向上动画在收集视图向左或向右滚动之前停止,但滚动时左/右浮动仍然存在。

当然不是最优雅的解决方案,但它有效。