画一条可以像Swift中的Xcode助手编辑器那样伸展的线

当谈到在Swift中绘制线条时,大多数解决方案都要覆盖UIView中的drawRect函数,但我正在寻找一种更动态的绘制线条的方法。

我有一个按钮,我希望能够从这个按钮拖动到下一个按钮。 在拖动时,我想画一条从起点到当前触摸位置的线条(就像Xcode中的助理编辑器在从一件事物拖到另一件物品时的工作方式),但我不知道如何绘制线条我从一个按钮拖到另一个按钮。

所以我的问题是:如何从一个起始位置动态绘制一条线到当前的“触摸”位置(就像Xcode中的助理编辑器一样)?

您可以使用UIPanGestureRecognizer来获取手势事件并使用UIPanGestureRecognizer绘制CALayer

UIPanGestureRecognizer有一些手势状态,在这种情况下,我们需要处理三种状态来绘制线条。 让我们将整个动作分成小块,以便更容易弄清楚该怎么做。

在开始之前,有一件事你必须要知道。

 // We can get current touch position via gesture recognizer. let currentPanPoint = panRecognizer.location(in: self.view) 
  1. 获取行起点并在状态UIGestureRecognizerState.began创建CALayer
 case .began: panGestureStartPoint = currentPanPoint self.view.layer.addSublayer(lineShape) 
  1. 获取状态UIGestureRecognizerState.changed行结束点并创建UIBezierPath ,将CGPathUIBezierPath分配给CALayer以绘制该行。
 case .changed: let linePath = UIBezierPath() linePath.move(to: panGestureStartPoint) linePath.addLine(to: currentPanPoint) lineShape.path = linePath.cgPath 
  1. 从状态UIGestureRecognizerState.end布局中删除该行。
 case .ended: lineShape.path = nil lineShape.removeFromSuperlayer() 

结合上面的片段,这里是示例代码。

 class ViewController: UIViewController { @IBOutlet var dragFrom: UILabel! private lazy var lineShape: CAShapeLayer = { let lineShape = CAShapeLayer() lineShape.strokeColor = UIColor.blue.cgColor lineShape.lineWidth = 2.0 return lineShape }() private var panGestureStartPoint: CGPoint = .zero private lazy var panRecognizer: UIPanGestureRecognizer = { return UIPanGestureRecognizer(target: self, action: #selector(panGestureCalled(_:))) }() override func viewDidLoad() { super.viewDidLoad() self.dragFrom.addGestureRecognizer(panRecognizer) } // MARK: Selectors func panGestureCalled(_: UIPanGestureRecognizer) { let currentPanPoint = panRecognizer.location(in: self.view) switch panRecognizer.state { case .began: panGestureStartPoint = currentPanPoint self.view.layer.addSublayer(lineShape) case .changed: let linePath = UIBezierPath() linePath.move(to: panGestureStartPoint) linePath.addLine(to: currentPanPoint) lineShape.path = linePath.cgPath case .ended: lineShape.path = nil lineShape.removeFromSuperlayer() default: break } } } 

它就是这样的。 http://sofzh.miximages.com/ios/5JsFeoB.gifv

如果您想了解更多详细信息,请参阅Apple开发人员指南中的教程。 了解如何使用Bezier Path绘制形状