【问题标题】:Limiting vertical movement of UIAttachmentBehavior inside a UICollectionView限制 UICollectionView 内 UIAttachmentBehavior 的垂直移动
【发布时间】:2014-05-05 17:23:06
【问题描述】:

我有一个水平的UICollectionView 和一个自定义的UICollectionViewFlowLayout,每个单元格上都设置了一个UIAttachmentBehavior,以便在左右滚动时给人一种有弹性的感觉。该行为具有以下属性:

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

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

当集合视图在新添加的单元格静止之前向左或向右滚动时,我开始出现的问题。将左右弹性添加到单元格已经添加的上下一个。这会导致单元格中出现非常奇怪的圆周运动。

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

【问题讨论】:

  • 让它保持原样,这很有趣。
  • 您使用的是自定义布局吗?然后确保在布局而不是单元格中添加运动效果。
  • 你有没有解决过这个问题(以一种优雅的方式)?
  • 不,到目前为止,我唯一的解决方案是我在下面发布的解决方案。

标签: ios objective-c uicollectionview uikit-dynamics


【解决方案1】:

解决此问题的一种方法是使用附件行为的继承 .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来开启和关闭限位功能。

【讨论】:

    【解决方案2】:

    如果您使用的是 iOS 9 及更高版本,那么附件类中的滑动功能将非常适合该工作:

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

    使用方便,滑动效果非常好Apple documentation

    【讨论】:

    • 你能提供一个如何使用它的例子吗?该文档对我和其他许多人来说都是完全神秘的。
    【解决方案3】:

    您是否尝试过手动从带有CALayerremoveAllAnimations 的单元格中删除动画?

    【讨论】:

    • UICollectionViewFlowLayout 子类中你究竟会在哪里做呢?
    • 再次检查后,最好回顾一下您是如何创建行为三(父/子行为)的。您也可以发布该代码吗?
    【解决方案4】:

    当集合视图开始滚动时,您会想要移除该行为,或者可能会大大降低弹性,以便它平稳而快速地停止。如果你仔细想想,你所看到的是你所描述的依恋行为的现实运动。

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

    【讨论】:

    • 当集合视图向左或向右滚动时,我仍然希望单元格有弹性。单元格边界上的碰撞行为不允许这样做。
    【解决方案5】:

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

    这进入 func identifyPanGesture(sender: 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)
    

    【讨论】:

      【解决方案6】:

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

      这样我可以确保向上动画在集合视图向左或向右滚动之前停止,而且在滚动时左/右弹性仍然存在。

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

      【讨论】:

        猜你喜欢
        • 2018-05-09
        • 2019-01-07
        • 2019-10-04
        • 2017-06-17
        • 2021-11-28
        • 2018-11-09
        • 2015-05-31
        • 2014-08-19
        • 1970-01-01
        相关资源
        最近更新 更多