Ios 自定义UICollectionViewFlowLayout上的插值问题

Ios 自定义UICollectionViewFlowLayout上的插值问题,ios,ios6,core-animation,uicollectionview,uicollectionviewlayout,Ios,Ios6,Core Animation,Uicollectionview,Uicollectionviewlayout,我对自定义UICollectionViewFlowLayout有问题 就像这个视频显示的,当我的细胞反弹回中心(0:12-0:16)时,我的变换插值失败,它在1帧内跳到中心位置 我隔离了这个问题,它在distanceToCenterX==0.0f时出现(下面的代码) 这是一个distanceToCenterX的printf,用于对中心单元格多次调用此方法: -92.000000 -91.500000 -91.000000 -90.

我对自定义UICollectionViewFlowLayout有问题

就像这个视频显示的,当我的细胞反弹回中心(0:12-0:16)时,我的变换插值失败,它在1帧内跳到中心位置

我隔离了这个问题,它在
distanceToCenterX==0.0f
时出现(下面的代码)

这是一个
distanceToCenterX
printf
,用于对中心单元格多次调用此方法:

-92.000000           
-91.500000           
-91.000000           
-90.500000           
-90.000000           
-89.500000           
-89.000000         
-88.500000
0.000000 
您可以看到它是如何从
-88.5000
突然跳到
0.00
的,我该怎么做才能平滑过渡并避免1帧跳转

代码(免责声明,摘自苹果示例和a)

static const CGfloat ACTIVE_DISTANCE=100.0f
-(void)setCellAttributes:(UICollectionViewLayoutAttributes*)visibleRect:(CGRect)visibleRect与CentralCellindeXPath:(NSIndexPath*)路径的属性
{
//首先设置属性的常规位置
[self-setGeneralPositionForAttributes:(HILayoutAttributes*)具有CentralAttributesIndexPath:path的属性];
//然后调整变换
CGFloat distanceToCenterX=CGRectGetMidX(visibleRect)-attributes.center.x;
//
//当DistanceToCenter为0时,问题会出现
//
CGFloat normalizedDistance=中心距离/活动距离;
BOOL isLeft=((hilayouttributes*)属性).generalPosition==kGeneralCellPosition\u left)?是:否;
CATTransferorM3D transform=CATTransferorM3D实体;
transform.m34=-1/(4.6777*self.itemSize.width);
if(ABS(距离中心)<有效距离){
如果(ABS(距离中心)<平移距离){
transform=CATTransformerM3dTranslate(CATTransformorM3dEntity,
((流量偏移*绝对值(距离中心))/平移距离),
0,
(1-ABS(标准化距离))*40000+(isLeft?200:0);
}
transform.m34=-1/(4.6777*self.itemSize.width);
变换=CATTransferM3dRotate(变换,1*ABS(标准化距离)*45*MμPI/180,0,1,0);
}否则{
transform=CATTransformerM3DTTranslate(转换,流量偏移,0,0);
transform=CATTransformerM3dRotate(transform,1*45*M_PI/180,0,1,0);
attributes.zIndex=0;
}
attributes.transform3D=变换;
}

如何避免这种情况发生?

我在Erica Sadun的《iOS 6开发者食谱》(第11章,配方5)中讨论了同样的问题

书中还有一个自定义UICollectionViewFlowLayout的示例,它展示了我遇到的相同问题

我在IRC上和Erica谈过这件事,我们一致认为UICollectionViewLayout中似乎有一个bug,她提到她不久前在雷达上看到了类似的东西,所以可能已经报告了

在她的书中,她为她的开源代码做了一个或多或少丑陋的变通方法,实际上你可以看看她的解决方案。这并不优雅,但它是一个完全有效的解决方法

proposedContentOffset.x
等于0,或者
collectionViewContentSize.width-bounds.width
时,她基本上会发出一个关于
targetContentOffsetForProposedContentOffset:WithCrollingVelocity:
的通知(
boundsSize=self.collectionView.bounds.Size

当scrollView最终减速到
所需的点时,控制器侦听该通知并基本上重新调整CollectionView的中心位置

- (void) scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    if (CGPointEqualToPoint(desiredPoint, CGRectNull.origin))
        return;

    CGRect rect = scrollView.bounds;
    rect.origin = desiredPoint;
    [self.collectionView scrollRectToVisible:rect animated:YES];

    desiredPoint = CGRectNull.origin;
}
希望这对其他人有帮助

CGPoint desiredPoint = CGPointMake(proposedContentOffset.x + offsetAdjustment, proposedContentOffset.y);

if ((proposedContentOffset.x == 0) || (proposedContentOffset.x >= (self.collectionViewContentSize.width - boundsSize.width)))
{
    NSNotification *note = [NSNotification notificationWithName:@"PleaseRecenter" object:[NSValue valueWithCGPoint:desiredPoint]];
    [[NSNotificationCenter defaultCenter] postNotification:note];
    return proposedContentOffset;
}
- (void) scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    if (CGPointEqualToPoint(desiredPoint, CGRectNull.origin))
        return;

    CGRect rect = scrollView.bounds;
    rect.origin = desiredPoint;
    [self.collectionView scrollRectToVisible:rect animated:YES];

    desiredPoint = CGRectNull.origin;
}