Search code examples
iosswifttouchesbegan

touchesMoved within restraints?


I've got view that I'm dragging on the screen. My touches began/moved/ended code works until I try to keep the view from not going any higher than when it starts out.

The endgoal effect is I'm wanting the user to be able to drag a UIImageView that is like 100pixels above a textview ontop of the textview, and once the "touchesEnded" is called it'll animate back to its original position and run appropriate code if the user dropped it on the text field.

I know in theory how to code all of that, I just can't get the actual movement to work.

To keep the view from ever going higher than where it starts out, I tried:

 override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        let position = touch.location(in: self.superview)
        if position.y >= originalY // calculated in touches began with  originalY = self.center.x  {
        self.center = CGPoint(x: originalX, y: position.y)

}

But that creates some weird side effects where I click and drag down. The view stays where it's at, and it's only until after the view makes it down past my textfield/ other buttons near the top of the screen that it snaps to my position and starts scrolling up and down.

Any ideas how to only let my view's Y be moved up to where it started out and down to a certain point without all these weird behaviors?

Edit:

I got rid of the if check on the Y and the dragging worked as expected, but once I made it down below my textfield/buttons area up top, when I'm doing my touchesEnding and resetting my X and Y back up to the top, my view stops just below the textfield/buttons. So it looks like for some reason my view is getting hung up on other elements on the screen.


Solution

  • Two things:

    Reverse y

    Note that y is 0 at the top of a view and height at the bottom. Take this into account when making constraints on y. Print position at touchesDidMove: for more insight.

    Subviews

    Other subviews might steal your touchEvents. Implement touchesCancelled(with:) for more insight, and make sure that your movable views are in front of other views

    If other subviews takes the touchEvents, when the touch returns to your view it will trigger touchesBegan(with:) again, and will offset your origin.