Search code examples
iosswiftswift2uigesturerecognizercgrect

Draw a rectangle the starting point and follow my movement to end the gesture in Swift


I asked a question on stackoverflow and received a perfect answer to my case.

To get the start point and end point of UIPanGestureRecognizer, use the code:

var view = UIView()

func panGestureMoveAround(gesture: UIPanGestureRecognizer) {

    var locationOfBeganTap: CGPoint

    var locationOfEndTap: CGPoint

    if gesture.state == UIGestureRecognizerState.Began {
        locationOfBeganTap = gesture.locationInView(view)
    } else if gesture.state == UIGestureRecognizerState.Ended {
        locationOfEndTap = gesture.locationInView(view)
    }
}

And for better viewing, I would draw a rectangle that caught the starting point and auto-resize to complete the movement.

How could I draw a rectangle the starting point and follow my movement to end the gesture?


Solution

  • You need to create a subclass of UIView call it something like RectView and like this:

    @IBDesignable
    class RectView: UIView {
        @IBInspectable var startPoint:CGPoint?{
            didSet{
                self.setNeedsDisplay()
            }
        }
    
        @IBInspectable var endPoint:CGPoint?{
            didSet{
                self.setNeedsDisplay()
            }
        }
    
        override func drawRect(rect: CGRect) {
            if (startPoint != nil && endPoint != nil){
                let path:UIBezierPath = UIBezierPath(rect: CGRectMake(min(startPoint!.x, endPoint!.x),
                min(startPoint!.y, endPoint!.y),
                fabs(startPoint!.x - endPoint!.x),
                fabs(startPoint!.y - endPoint!.y)))
            path.stroke()
        }
        }
    
    }
    

    Then in your view controller you can say something like:

    @IBAction func panGestureMoveAround(sender: UIPanGestureRecognizer) {
            var locationOfBeganTap: CGPoint
    
            var locationOfEndTap: CGPoint
    
            if sender.state == UIGestureRecognizerState.Began {
                locationOfBeganTap = sender.locationInView(rectView)
                rectView.startPoint = locationOfBeganTap
                rectView.endPoint = locationOfBeganTap
    
            } else if sender.state == UIGestureRecognizerState.Ended {
                locationOfEndTap = sender.locationInView(rectView)
                            rectView.endPoint = sender.locationInView(rectView)
            } else{
                rectView.endPoint = sender.locationInView(rectView)
            }
        }
    

    Swift 5 version

    class RectView: UIView {
        var startPoint: CGPoint? {
            didSet {
                setNeedsDisplay()
            }
        }
    
        var endPoint: CGPoint? {
            didSet {
                setNeedsDisplay()
            }
        }
    
        override func draw(_ rect: CGRect) {
            guard let startPoint = startPoint, let endPoint = endPoint else {
                return
            }
    
            let path = UIBezierPath(
                rect: CGRect(
                    x: min(startPoint.x, endPoint.x),
                    y: min(startPoint.y, endPoint.y),
                    width: abs(startPoint.x - endPoint.x),
                    height: abs(startPoint.y - endPoint.y)
                )
            )
            path.stroke()
        }
    }
    
    @objc func panGestureMoveAround(_ sender: UIPanGestureRecognizer) {
        var locationOfBeganTap: CGPoint
    
        switch sender.state {
        case .began:
            locationOfBeganTap = sender.location(in: rectView)
            rectView.startPoint = locationOfBeganTap
            rectView.endPoint = locationOfBeganTap
        case .changed:
            rectView.endPoint = sender.location(in: rectView)
        case .ended:
            rectView.endPoint = sender.location(in: rectView)
        default:
            break
        }
    }