如何在平移手势事件期间转换一条线?

Posted

技术标签:

【中文标题】如何在平移手势事件期间转换一条线?【英文标题】:How to transform a line during pan gesture event? 【发布时间】:2014-11-25 00:58:52 【问题描述】:

我正在创建一个流程图,当用户拖动一个节点时,我想移动连接到它的线。在节点的 pan 处理程序事件中,我实现了一个 CGAffineTransform 来转换线,但它不能平滑地移动线。知道其他流程图应用程序如何处理这个问题吗?

func panHandler(sender: UIPanGestureRecognizer) 

        else if (sender.state == .Changed)
        
            let translation = sender.translationInView(self)
            sender.view!.center = CGPointMake(originalCenter.x + translation.x, originalCenter.y + translation.y)


           //rv is the connected line, created at an other place like:
           //let w = GraphViewController.calcLength(e.x, y0: e.y, x1: e2.x, y1: e2.y)
           //rv = UIView(frame: CGRectMake(0, 0, CGFloat(w), 1.0))
           //var angle = GraphViewController.calcAngle(e.x, y0: e.y, x1: e2.x, y1: e2.y)
           //rv.transform = CGAffineTransformMakeRotation(CGFloat(angle))

            var angle = GraphViewController.calcAngle(e!.x, y0: e!.y, x1: r.destination!.x, y1:r.destination!.y)
            rv!.transform = CGAffineTransformMakeRotation(CGFloat(angle))

        
    

【问题讨论】:

您是否尝试将 rv!.transform = CGAffineTransformMakeRotation(CGFloat(angle)) 放入动画块中? 你确定这个角度是用弧度而不是度数来衡量的吗? CGAffineTransformMakeRotation 所需的弧度角。我不记得它在 Swift 中的样子,但在 Objective C 中会是这样的: [UIView animateWithDuration:0.05 animations:^ rv.transform = CGAffineTransformMakeRotation(M_PI * angle); ]; 【参考方案1】:

因为您不需要在线上的任何触摸事件,我们可以使用普通的CAShapeLayer 并在 pan 上更新其路径。我假设你想为这条线设置一些锚点。

为你的线定义一些锚点

endOfLineAnchor = CGPoint(x: view.bounds.width / 2, y: view.bounds.height * 0.8)

创建一些视图以将其附加到

ballView = createBallView()
ballView.center = CGPoint(x: view.bounds.width / 2, y: view.bounds.height / 2)

添加图层和视图

    lineLayer = CAShapeLayer()
    lineLayer.strokeColor = UIColor.blackColor().CGColor
    lineLayer.path = pathFromBallToAnchor()
    view.layer.addSublayer(lineLayer)
    view.addSubview(ballView)

在平移时更新图层路径

    else if (sender.state == .Changed)
    
        let translation = sender.translationInView(self.view)
        sender.view!.center = CGPointMake(originalCenter.x + translation.x, originalCenter.y + translation.y)
        CATransaction.begin()
        CATransaction.setValue(kCFBooleanTrue, forKey: kCATransactionDisableActions)
        lineLayer.path = pathFromBallToAnchor()
        CATransaction.commit()
    

CATransaction 的原因是我们想要禁用隐式动画。

构造路径:

    func pathFromBallToAnchor() -> CGPathRef 
        var bazier = UIBezierPath()
        bazier.moveToPoint(ballView.center)
        bazier.addLineToPoint(endOfLineAnchor)
        return bazier.CGPath
    

结果:

【讨论】:

以上是关于如何在平移手势事件期间转换一条线?的主要内容,如果未能解决你的问题,请参考以下文章

按下按钮(子视图)时不要在超级视图上处理平移手势

android手势如何平移控件

为啥我的平移手势只能在第二次输入后识别事件?

如何在半视图上实现滑动手势和在另一半视图上实现平移手势?

在玩游戏期间禁用 iOS 多任务手势识别器

基于平移手势翻译的滚动scrollview