我一直在玩斯坦福大学讲座/ WWDC的视频,它向你展示了如何创建一个手势来同时收缩/缩放。它返回一个CGAffineTransform,然后将其应用于UIView。
这一切都很好,但我试图让它变得更加流畅,并在代码中添加一些减速。为此,我尝试在每次UIGestureRecognizerStateChanged调用时存储转换矩阵,然后当我收到UIGestureRecognizerStateEnded时,存储最后更改的矩阵和结束的矩阵之间的增量:
- (void)handleTransform:(TransformGestureRecognizer *)transformRecognizer
{
CGAffineTransform transform = transformRecognizer.transform;
// cancel any previous animation updates
[UIView cancelPreviousPerformRequestsWithTarget:self selector:@selector(decelerateView:) object:transformRecognizer.view];
if(transformRecognizer.state == UIGestureRecognizerStateBegan)
{
transform = CGAffineTransformConcat(transformRecognizer.view.transform, transform);
transformRecognizer.transform = transform;
}
else if(transformRecognizer.state == UIGestureRecognizerStateChanged)
{
changingTransform = transform;
}
else if(transformRecognizer.state == UIGestureRecognizerStateEnded)
{
// get transform difference
releaseTransformDiff.a = (transform.a - changingTransform.a);
releaseTransformDiff.b = (transform.b - changingTransform.b);
releaseTransformDiff.c = (transform.c - changingTransform.c);
releaseTransformDiff.d = (transform.d - changingTransform.d);
releaseTransformDiff.tx = (transform.tx - changingTransform.tx);
releaseTransformDiff.ty = (transform.ty - changingTransform.ty);
// start updating deceleration animation
[self performSelector:@selector(decelerateView:) withObject:transformRecognizer.view afterDelay:1.0/60.0];
}
transformRecognizer.view.transform = transform;
}然后,我有一个用于设置减速动画的decelerateView:方法:
#define DECELERATION_RATE 0.9
- (void)decelerateView:(UIView *)view
{
releaseTransformDiff.a = releaseTransformDiff.a * DECELERATION_RATE;
releaseTransformDiff.b = releaseTransformDiff.b * DECELERATION_RATE;
releaseTransformDiff.c = releaseTransformDiff.c * DECELERATION_RATE;
releaseTransformDiff.d = releaseTransformDiff.d * DECELERATION_RATE;
releaseTransformDiff.tx = releaseTransformDiff.tx * DECELERATION_RATE;
releaseTransformDiff.ty = releaseTransformDiff.ty * DECELERATION_RATE;
view.transform = CGAffineTransformMake(view.transform.a + releaseTransformDiff.a,
view.transform.b + releaseTransformDiff.b,
view.transform.c + releaseTransformDiff.c,
view.transform.d + releaseTransformDiff.d,
view.transform.tx + releaseTransformDiff.tx,
view.transform.ty + releaseTransformDiff.ty);
[self performSelector:@selector(decelerateView:) withObject:view afterDelay:1.0/60.0];
}这有时会起作用,但有时它会突然停止,而且几乎不会减速我所做的任何旋转。我想我没有正确计算这两个矩阵的增量。执行此操作的正确方法是什么?
发布于 2012-05-09 02:45:37
CGAffineTransformation是表示3 x 3矩阵的简化数据结构:
|a b 0|
|c d 0|
|tx ty 1|通过将a3x1矩阵乘以上述矩阵来变换一个点。
|a b 0|
[x' y' 1] = [x y 1] X |c d 0|
|tx ty 1|要创建缩放仿射变换,请将a设置为缩放x轴的因子,将d设置为缩放y轴的因子。要创建平移仿射变换,请将tx设置为沿x轴移动的值,将ty设置为沿y轴移动的值。
这个问题中使用的技术将适用于仅仅是缩放或平移变换(或这两种类型的变换的组合)的仿射变换。这是因为受影响的四个值确实是线性且独立变化的。
为了创建角度A的旋转仿射变换,将a设置为cos A,b设置为sin A,c设置为-sin A,d设置为cos A。由于sin和cos不是线性函数,因此问题中提出的增量更改将无法正常工作。更复杂的是,两个转换的组合是表示这些转换的两个矩阵的乘法。在涉及旋转的情况下,所得到的矩阵将不会与将导致略有不同的变换的矩阵线性不同。
构建增量转换的方法是更改转换构建函数调用的输入,而不是直接对生成的矩阵进行模糊处理。
https://stackoverflow.com/questions/10501243
复制相似问题