在UICollectionView中禁用UIAttachmnetBehavior的垂直移动

时间:2014-06-20 18:18:28

标签: ios uicollectionview uikit-dynamics uidynamicbehavior uidynamicanimator

我在水平UICollectionView

中尝试模仿消息app spring动画

我在UICollectionViewFlowLayout子类中使用了UIAttachmentBehavior。但问题是,当我水平滚动时,细胞也会垂直和水平移动,不知何故是一个旋转运动!

enter image description here

enter image description here

我遵循了本教程:
implementing a bouncy uicollectionviewlayout with uikitdynamics

并在我的collectionView中使用。我还关注了iOS 7上的WWDC 2013会话217-Exploring Scroll Views,但问题仍然存在! 有谁知道我该怎么解决这个问题?

-(id)initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if (self){
    _dynamicAnimator = [[UIDynamicAnimator alloc] initWithCollectionViewLayout:self];
}
return self;
}

- (void)prepareLayout{

    [super prepareLayout];

    CGSize contentSize = [self collectionViewContentSize];
    NSArray *items = [super layoutAttributesForElementsInRect:CGRectMake(0, 0, contentSize.width, 500)];

    if (items.count != _dynamicAnimator.behaviors.count) {
        [_dynamicAnimator removeAllBehaviors];

        for (UICollectionViewLayoutAttributes *item in items) {
            UIAttachmentBehavior *springBehavior = [[UIAttachmentBehavior alloc] initWithItem:item attachedToAnchor:item.center];
            springBehavior.length = 0.f;
            springBehavior.damping = 0.5f;
            springBehavior.frequency = 0.8f;

            [_dynamicAnimator addBehavior:springBehavior];
        }
    }
}

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{
    return [_dynamicAnimator itemsInRect:rect];
}

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{
    return [_dynamicAnimator layoutAttributesForCellAtIndexPath:indexPath];
}

- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{
    CGFloat scrollDelta = newBounds.origin.x - self.collectionView.bounds.origin.x;
    CGPoint touchLocation = [self.collectionView.panGestureRecognizer locationInView:self.collectionView];

for (UIAttachmentBehavior *springBehavior in _dynamicAnimator.behaviors) {
    CGPoint anchorPoint = springBehavior.anchorPoint;
    CGFloat touchDistance = fabsf(touchLocation.x - anchorPoint.x);
    CGFloat resistanceFactor = 0.002;

    UICollectionViewLayoutAttributes *attributes = springBehavior.items.firstObject;

    CGPoint center = attributes.center;

    float resistedScroll = scrollDelta * touchDistance * resistanceFactor;
    float simpleScroll = scrollDelta;

    float actualScroll = MIN(abs(simpleScroll), abs(resistedScroll));
    if(simpleScroll < 0){
        actualScroll *= -1;
    }

    center.x += actualScroll;
    attributes.center = center;

    [_dynamicAnimator updateItemUsingCurrentState:attributes];
}

    return NO;
}

3 个答案:

答案 0 :(得分:3)

我的应用中遇到了同样的问题。问题是这一行:  UIAttachmentBehavior *springBehavior = [[UIAttachmentBehavior alloc] initWithItem:item attachedToAnchor:item.center];

问题是项目的中心返回带小数的浮点数。 iOS然后将它们舍入为具有0位小数的浮点数,导致锚点不能很好地居中,因此项目会反弹。

解决方案是确保物品的框架在锚定之前可以被高度和宽度整除2。然后验证item.center是否返回没有小数的浮点数的X和Y值,并且动画可以正常工作。

注意:即使在iOS7中工作也很完美我看到iOS8中的问题与此问题类似,但此解决方案不起作用。

答案 1 :(得分:0)

我在iOS 8中看到完全相同的问题 - 似乎虽然UICollisionBehavior允许创建边界,但UIAttachmentBehavior也不存在(尽管类文档为UIAttachmentBehavior提及了它)。我认为短期解决方案可能只是转移到UIDynamicItemBehavior,这看起来更灵活。有兴趣知道从iOS 7到iOS 8的变化。

答案 2 :(得分:0)

我有这个问题 - iOS8。

现在它已经消失了,感谢这篇文章。

我将补充视图添加到已经使UIDynamics运行良好的UICollectionView中。然后我添加了一些基于常规单元框架的补充视图。计算将返回高度的浮点数(不是0小数)。我想Pauls说,iOS然后必须进行一些舍入,现在创建一个我不想要的y-delta。这就是引发摆动运动的原因 通过舍入我的optionalView高度,问题就消失了。我得到7.5的一致中心,所以我的高度不能被2整除,但它仍在工作。

这里我的补充视图现在是如何计算的

UICollectionViewLayoutAttributes *attributes = [self.dynamicAnimator layoutAttributesForCellAtIndexPath:indexPath];
// put supp view at beginning of cell
// round off height or wierd oscillations will begin as iOS must round also
CGRect suppViewFrame = CGRectMake(attributes.frame.origin.x - 44.0 / 2,
                                  attributes.frame.origin.y - 44.0,
                                  44.0,
                                  roundf(44.0 + attributes.frame.size.height / 2));

我添加的所有内容都是CGRect计算高度部分的roundf 瞧 - 它正在发挥作用。
希望这有助于某人 - 快乐编码