ios – 跟随手指的旋转动画,沿着圆的外部路径的uibutton

ios – 跟随手指的旋转动画,沿着圆的外部路径的uibutton,第1张

概述我正在寻找一些指导,开始计算跟踪手指运动的动画,并沿着圆圈的外部路径移动UIButtons的集合 我想它会有一种左轮手q的感觉.就像每个人在底部锁定到位 或者喜欢通过其中一个滑动插件滑动 提前致谢 ( GitHub上的示例代码) 这并不是那么困难,只涉及很多三角函数. 现在,我现在要描述的不是动画,因为你要求它跟踪手指在标题中的位置.动画将涉及其自己的计时功能,但由于您正在使用触摸手势,我们可以使 我正在寻找一些指导,开始计算跟踪手指运动的动画,并沿着圆圈的外部路径移动UIbuttons的集合

我想它会有一种左轮手q的感觉.就像每个人在底部锁定到位

或者喜欢通过其中一个滑动插件滑动

提前致谢

解决方法 ( GitHub上的示例代码)

这并不是那么困难,只涉及很多三角函数.

现在,我现在要描述的不是动画,因为你要求它跟踪手指在标题中的位置.动画将涉及其自己的计时功能,但由于您正在使用触摸手势,我们可以使用此事件具有的固有时序,并相应地旋转视图. (TL; DR:用户保持移动的时间,而不是隐式计时器).

跟踪手指

首先,让我们定义一个跟踪角度的方便类,我将其称为DialVIEw.它实际上只是UIVIEw的子类,具有以下属性:

DialVIEw.h

@interface DialVIEw : UIVIEw@property (nonatomic,assign) CGfloat angle;@end

DialVIEw.m

- (voID)setAngle:(CGfloat)angle{    _angle = angle;    self.transform = CGAffinetransformMakeRotation(angle);}

UIbuttons可以包含在这个视图中(我不确定你是否希望按钮负责旋转?我将使用UIPanGestureRecognizer,因为它是最方便的方式).

让我们构建一个视图控制器,它将在我们的DialVIEw中处理一个平移手势,让我们也保持对DialVIEw的引用.

MyVIEwController.h

@class DialVIEw;@interface VIEwController : UIVIEwController// The prevIoUsly defined dial vIEw@property (nonatomic,weak) IBOutlet DialVIEw *dial;// UIPanGesture selector method    - (IBAction)dIDReceiveSpinPanGesture:(UIPanGestureRecognizer*)gesture;@end

这取决于你如何连接平移手势,个人而言,我在nib文件上做了它.现在,这个功能的主体:

MyVIEwController.m

- (IBAction)dIDReceiveSpinPanGesture:(UIPanGestureRecognizer*)gesture{    // This struct encapsulates the state of the gesture    struct state    {        CGPoint touch;          // Current touch position        CGfloat angle;          // Angle of the vIEw        CGfloat touchAngle;     // Angle between the finger and the vIEw        CGPoint center;         // Center of the vIEw    };    // Static variable to record the beginning state    // (alternatively,use a @property or an _ivar)    static struct state begin;    CGPoint touch = [gesture locationInVIEw:nil];    if (gesture.state == UIGestureRecognizerStateBegan)    {        begin.touch  = touch;        begin.angle  = self.dial.angle;        begin.center = self.dial.center;        begin.touchAngle = CGPointAngle(begin.touch,begin.center);    }    else if (gesture.state == UIGestureRecognizerStateChanged)    {        struct state Now;        Now.touch   = touch;        Now.center  = begin.center;        // Get the current angle between the finger and the center        Now.touchAngle = CGPointAngle(Now.touch,Now.center);        // The angle of the vIEw shall be the original angle of the vIEw        // plus or minus the difference between the two touch angles        Now.angle = begin.angle - (begin.touchAngle - Now.touchAngle);        self.dial.angle = Now.angle;    }    else if (gesture.state == UIGestureRecognizerStateEnded)    {        // (To be Continued ...)    }}

CGPointAngle是我发明的一种方法,它只是atan2的一个很好的包装器(如果你现在调用它我会抛出CGPointdistance!):

CGfloat CGPointAngle(CGPoint a,CGPoint b){    return atan2(a.y - b.y,a.x - b.x);}CGfloat CGPointdistance(CGPoint a,CGPoint b){    return sqrt(pow((a.x - b.x),2) + pow((a.y - b.y),2));}

关键在于,有两个角度可以跟踪:

>视图本身的角度
>手指与视图中心之间形成的角度.

在这种情况下,我们希望视图的角度为originalAngle deltaFinger,这就是上面的代码所做的,我只是在结构中封装了所有的状态.

检查半径

如果要跟踪“视图边框”,则应使用CGPointdistance方法并检查begin.center和Now.finger之间的距离是否为特定值.

这是你的功课!

回击

好的,现在,这部分是一个实际的动画,因为用户不再控制它.

可以通过设置一组角度来实现捕捉,当手指释放手指时(手势结束),快速回到它们,如下所示:

else if (gesture.state == UIGestureRecognizerStateEnded){    // Number of "buttons"    NSInteger buttons = 8;    // Angle between buttons    CGfloat angledistance = M_PI*2 / buttons;    // Get the closest angle    CGfloat closest = round(self.dial.angle / angledistance) * angledistance;    [UIVIEw animateWithDuration:0.15 animations:^{        self.dial.angle = closest;    }];}

按钮变量,只是视图中按钮数量的替身.该方程实际上非常简单,它只是滥用舍入函数来逼近闭合角度.

总结

以上是内存溢出为你收集整理的ios – 跟随手指的旋转动画,沿着圆的外部路径的uibutton全部内容,希望文章能够帮你解决ios – 跟随手指的旋转动画,沿着圆的外部路径的uibutton所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1054105.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存