4
votes

I'm new in Swift and I'm trying to let the user draw a rectangle (touching and dragging) to select an area of an image just like when cropping but I don't want to crop I just want to know the CGRect the user created.

So far I have a .xib with a UIImage inside and its ViewController. I want to draw above the image but every tutorial I found about drawing is about subclassing UIView, override drawRect and put that as the xib class.

1
What's wrong with subclassing UIView and override drawRect? - Gwendal Roué

1 Answers

5
votes

I figured it out. I just created a uiview and change its frame depending on the touches events

let overlay = UIView()
var lastPoint = CGPointZero

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
    overlay.layer.borderColor = UIColor.blackColor().CGColor
    overlay.backgroundColor = UIColor.clearColor().colorWithAlphaComponent(0.5)
    overlay.hidden = true
    self.view.addSubview(overlay)

}

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

    //Save original tap Point
    if let touch = touches.first {
        lastPoint = touch.locationInView(self.view)
    }   
}

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
    //Get the current known point and redraw
    if let touch = touches.first {
        let currentPoint = touch.locationInView(view)
        reDrawSelectionArea(lastPoint, toPoint: currentPoint)
    }
}

func reDrawSelectionArea(fromPoint: CGPoint, toPoint: CGPoint) {
    overlay.hidden = false

        //Calculate rect from the original point and last known point
        let rect = CGRectMake(min(fromPoint.x, toPoint.x),
        min(fromPoint.y, toPoint.y),
        fabs(fromPoint.x - toPoint.x),
        fabs(fromPoint.y - toPoint.y));

    overlay.frame = rect
}

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
    overlay.hidden = true

    //User has lift his finger, use the rect
    applyFilterToSelectedArea(overlay.frame)

    overlay.frame = CGRectZero //reset overlay for next tap
}