使用UIPanGestureRecognizer围绕某个点旋转UIView

时间:2012-11-30 11:58:29

标签: objective-c ios core-animation uigesturerecognizer uipangesturerecognizer

我正在尝试创建一个允许用户从窗口侧面拉出面板的动画。在右上方可以看到少量视图,通过拉动视图,视图将向外旋转,固定在屏幕的右下角。希望这些图像显示我想要实现的内容(右侧的纸张表示视图的一部分将被隐藏。我希望用户能够拖动它,而不是滑动或点击。< / p>

有人能指出我如何实现这一目标的正确方向吗?我对iOS中的动画很陌生。我已经完成了平移手势,但是我需要这一点来旋转。我可以设置视图的.center属性,但这样做只会将整个视图移动到那一点,所以我需要一个center来旋转,这实际上不是视图的中间,我认为?

enter image description here enter image description here

编辑:我写了一个有效的方法,但视图并没有“卡住”用户的手指。我可以用手指拉动,比方说,45度,但是视野会移动得更多。我不确定如何将它们同步,任何想法?

- (void) swipeSidebarOpen: (UIPanGestureRecognizer *) recognizer {
    //[self openOrCloseSideBar: YES];
    _sidebarView.layer.anchorPoint = CGPointMake(1.0, 1.0);
    _sidebarView.layer.position = CGPointMake(510, 330);

    UIView *shuttle = [recognizer view];

    if ([recognizer state] == UIGestureRecognizerStateBegan || [recognizer state] == UIGestureRecognizerStateChanged) {
        CGPoint vel = [recognizer velocityInView:[recognizer view]];

        if (vel.x > 0) {
            [recognizer view].transform = CGAffineTransformRotate([[recognizer view] transform], M_PI / 80.0f);
            [recognizer setTranslation: CGPointZero inView:[shuttle superview]];
        } else {
            [recognizer view].transform = CGAffineTransformRotate([[recognizer view] transform], -M_PI / 80.0f);
            [recognizer setTranslation: CGPointZero inView:[shuttle superview]];
        }
    }
}

3 个答案:

答案 0 :(得分:2)

有点晚了,但我写了一些代码来处理一个手指使用的平移,缩放和缩放。标准手势在微调工作方面缺乏准确性,或在驾驶室后面蹦蹦跳跳。

这两件事可能对你有所帮助。旋转手势目标方法能够从收缩识别器或平移器接受。您需要跟踪平移识别器的第一个触摸点的位置,因为您将计算其当前点与手势起点之间的角度。您还需要保存屏幕中心。对我来说,我把所有这些点都放到窗口的坐标系中,所以你必须选择你想要使用的那个并坚持下去。

CGFloat /* midpoint, startpoint, point */
CGPointAngleATan2(CGPoint mp, CGPoint sp, CGPoint p)
{
    CGFloat angle = 0;
    CGFloat sAngle = atan2(sp.y-mp.y,sp.x-mp.x);
    CGFloat pAngle = atan2(p.y-mp.y,p.x-mp.x);
    angle = pAngle-sAngle;
    return angle;
}


- (CGFloat)calculateRotation:(UIGestureRecognizer *)sender;
{
    CGFloat rotation;

    if ([sender respondsToSelector:@selector(rotation)]){
        rotation = [(UIRotationGestureRecognizer *)sender rotation];
    } else {
        // convert to window co-ordinates, app specific so change if needed
        CGPoint point = [sender locationInView:self.view.window];
        rotation = CGPointAngleATan2(screenCenter,firstTouch,point);
    }
    return rotation;
}

答案 1 :(得分:1)

默认情况下,视图会围绕其中心旋转,但您可以通过为视图anchorPoint设置另一个layer来更改该视图。 (您需要导入Core Animation才能执行此操作(QuartzCore.framework))。

锚点被标准化(X和Y都从0变为1)。默认情况下,它位于中心(0.5,0.5),但您想将其更改为右下角(1.0,1.0)。

myView.layer.anchorPoint = CGPointMake(1.0, 1.0);

更改anchorPoint将在屏幕上直观地移动您的视图,以便superview中视图图层的position与视图旋转的点相同。

myView.layer.position = theFixedHerePoint; // The point you are showing in your drawing...

例如:如果超级视图从(0,0)变为(100,100),那么myView的position应该是,右下角应为,不是myView的中心所在。如下图所示(X是anchorPoint(1,1)和位置(95,95))。 请注意,95只是一个任意值。

┌───────────────────┐
│ superview         │
│                   │
│      ┌──────────┐ │
│      │ myView   │ │
│      │          │ │
│      │          │ │
│      └──────────X │
└───────────────────┘

现在,当您平移时,您可以简单地设置适当的旋转变换,视图将围绕其右下角旋转。

答案 2 :(得分:0)

您需要做的是在平移时,在pangesturerecognizer的处理程序中,您需要为要平移的视图应用旋转变换。像self.SomeView.transform = CGAffineTransformMakeRotation(some rotation)一样。您需要对要应用的旋转量进行一些计算。同样,设置一个中心。