我正在尝试在水平 UICollectionView 中模拟消息应用程序弹簧动画
我在 UICollectionViewFlowLayout 子类中使用了 UIAttachmentBehavior。但问题是当我水平滚动时,单元格也会以某种方式垂直和水平移动!
我遵循了本教程:
使用 uikitdynamics 实现有弹性的 uicollectionviewlayout
并在我的 collectionView 中使用。我还关注了 WWDC 2013 session 217-Exploring Scroll Views on iOS 7。但问题仍然存在!
有谁知道我应该如何解决这个问题?
-(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;
}