David Lara
David Lara

Reputation: 51

touchesEnded not called when swiping a view on top of a tableview

I have a simple tableview with only rows containing text (the cells are standard UITableViewCell and I simply modify their .textLabel attribute).

I have programatically added an UIView to the tableview and made it to look like a red square over the table. I have also assigned a UIPanGestureRecognizer to this square view. The idea is to able to drag the square view all over the tableview.

I can see how the (overrided) functions touchesBegan and touchesCancelled are called normally. touchesEnded is only called if I do not swipe the square view, this is, just tapping, no dragging.

By reading similar posts I understood that the problem is that UIGestureRecognizer is recognizing a swipe, which overrides touchesEnded, but I don’t know how to deal with this.

Many thanks in advance for your help!!

Update to include code.

From TableViewController. Token is my custom view that I want to drag (the "square view" mentioned before).

override func viewDidAppear(animated: Bool) {
    let token = Token(frame: CGRect(x: 10, y: 10, width: 20, height: 20), color: UIColor.redColor())
    self.view.addSubview(token)
    self.view.bringSubviewToFront(token)
}

Token, my custom View:

class Token: UIView {
var lastLocation:CGPoint = CGPoint(x: 10, y: 10)

init(frame: CGRect, color: UIColor) {
    super.init(frame: frame)
    self.backgroundColor = color
    let panRecognizer = UIPanGestureRecognizer(target:self, action:"detectPan:")
    self.gestureRecognizers = [panRecognizer]
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

func detectPan(recognizer:UIPanGestureRecognizer) {
    let translation  = recognizer.translationInView(self.superview!)
    self.center = CGPointMake(lastLocation.x + translation.x, lastLocation.y + translation.y)
}

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    print("began")
    // Promote the touched view
    self.superview?.bringSubviewToFront(self)

    // Remember original location
    lastLocation = self.center
}

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
    print("touchesEnded")
}

}

Upvotes: 1

Views: 441

Answers (1)

Abhinav
Abhinav

Reputation: 38162

There is a property cancelsTouchesInView on UIPanGestureRecognizer. Set it to NO and it shall pass the touches to underneath UIView.

You can then implement touchesBegan function to move your view.

Upvotes: 1

Related Questions