将 UIKit Dynamics 添加到自定义 UICollectionViewFlowLayout。 dynamicAnimator 似乎使用默认布局

adding UIKit Dynamics to a custom UICollectionViewFlowLayout. dynamicAnimator seems to use default layout

我正在尝试将 UIDynamics 添加到自定义 UICollectionViewFlowLayout

我希望 dynamicAnimator 在滚动时为每个单元格设置动画。他们应该以更现实的方式表现,就像 iMessage 气泡一样。它们似乎会对滚动时施加在它们身上的物理力做出反应。我希望 dynamicAnimator 以相同的方式为我的单元格设置动画。我知道 dynamicAnimator 会非常快速地改变细胞的中心,从而产生对细胞施加物理力的错觉。我找到了一个教程,解释如何使用 UICollectionViewUIKit Dynamics tutorial with example project 执行此操作。我确实理解本教程的每一步。

我上传了一张图片来阐明我想要实现的目标。查看 image(我的声誉还没有高到 post 图片)。遵循本教程将生成看起来有点像布局 (2) 的布局。这非常接近我想要的。但是,我想更改一件事:单元格以 collectionView 为中心。我希望单元格的初始中心与布局 (1) 中的一样,而不是布局 (2) 中的那样。

在使用 dynamicAnimator 之前,我在 layoutAttributesForItemAtIndexPath 方法中设置了单元格的中心。但是,我需要找到一种方法来通知 dynamicAnimator 单元格的中心不是布局 (2) 中的,而是布局 (1) 中的。显然,我不知道如何融合来自布局的信息和来自动画师的信息。

因此,我将尝试重新表述我的问题。我如何融合来自布局的信息和来自动画师的信息?

包括一些代码:如何使上面教程中的示例看起来更像布局 (2)(因此如何更改单元格的初始中心)?我在哪里告诉 dynamicAnimator 单元格的中心应该在哪里?

该项目可以在上面教程的开头找到,名为 ASHSpringyCollectionView,结果类似于布局 (2)。

// 以下是问题的初始版本。为了更清晰,我重写了它(重写了这部分以上的所有内容)。为了完整起见,我在这里保留了这个旧版本的问题。

我正在尝试将 UIDynamics 添加到自定义 UICollectionViewFlowLayout。我正在使用 piemonte 的自定义 UICollectionViewFlowLayout PBJHexagon 它创建了一个漂亮的六边形布局。然而,为了实现这种特殊的布局,他在“layoutAttributesForItemAtIndexPath”-method 中更改了单元格的中心:

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{ 
NSInteger row = (NSInteger) CGFloat_nearbyint( CGFloat_floor(indexPath.row / _itemsPerRow) );
NSInteger col = indexPath.row % _itemsPerRow;

CGFloat horiOffset = ((row % 2) != 0) ? 0 : self.itemSize.width * 0.5f;
CGFloat vertOffset = 0;

UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
attributes.size = self.itemSize;
attributes.center = CGPointMake( ( (col * self.itemSize.width) + (0.5f * self.itemSize.width) + horiOffset),
                                 ( ( (row * 0.75f) * self.itemSize.height) + (0.5f * self.itemSize.height) + vertOffset) );
return attributes;
}

这很有魅力。但是,我想将 UIKit Dynamics 添加到我的应用程序中,以使其更具吸引力并创造更好的整体体验。 我在 objc.io 上学习了一个名为 'UICollectionView + UIKIT Dynamics' 的精彩教程。根据教程,我必须像这样更改方法:

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

这样做要求我替换计算单元格中心的代码。 我上传了一张图片来阐明它的样子。请参见上图(我的声誉还没有高到 post 图像)。我通过将上面的代码添加到 MyCollectionViewController 中的以下方法来实现左侧 (1) 的布局。但是,一旦我开始滚动,布局就会变回布局 (2)(也有一些难看的闪烁)。我猜这是因为 dynamicAnimator 处于控制之中并使用了看起来更像布局 (2) 的 layoutAttributes。

问题是我不知道如何告诉 dynamicAnimator 单元格的初始位置是什么,它不应该使用标准的 FlowLayout 中心。

MyCollectionViewController 中创建正确布局的方法..直到第一个滚动操作发生:

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
NSInteger row = (NSInteger) CGFloat_nearbyint( CGFloat_floor(indexPath.row / 2) ); // 2 = itemsPerRow
NSInteger col = indexPath.row % 2; // 2 = itemsPerRow
CGFloat horiOffset = ((row % 2) != 0) ? 0 : 60.f * 0.5f;
CGFloat vertOffset = 0;
 cell.center = CGPointMake( ( (col * 125.0f) + (0.5f * 125.0f) + horiOffset),
                                ( ( (row * 0.75f) * 125.0f) + (0.5f * 125.0f) + vertOffset) );

cell.backgroundColor = [UIColor orangeColor];
return cell;
}

毕竟,我的问题是如何使布局 (1) 成为一直使用的永久布局。因此,如何使 dynamicAnimator 使用布局 (1) 而不是布局 (2)?

你的所作所为毫无意义。您的代码显示了 layoutAttributesForItemAtIndexPath: 两个 实现。那是无稽之谈。只能有一个。

将动态动画器添加到集合视图布局是一项复杂、微妙的业务 — 不适合初学者。

  • 首先,您必须仅在您实际上正在制作动画时才吸引动态动画师。有些时候你在做动画,有些时候你不做。你没有给出动画的时间或理由,所以完全不清楚你想要动画的内容和时间。

  • 其次,您必须融合来自布局的信息和来自动画师的信息,仅针对那些实际正在处理的项目动画。

你没有做那样的事情,所以你的结果当然很奇怪。