Search code examples
swiftuitextfieldconstraintsuipangesturerecognizer

apply uipangesture to uitextfield


My swift code below applies a pangesture to a textfield that's it. The problem is when I type something into the textfield. The textfield goes back to its orginal constraind position. I just don't want it to revert when text is typed into the textfield. This is a constraint problem. If I remove the constraints I want it to. So to see this effect just copy the code into Xcode and apply storyboard constraints and you will see what I mean.

import UIKit
class fullScreen : UIViewController {

@IBOutlet var i : UItextField!


var g11 = UIPanGestureRecognizer()

override func viewDidLoad() {

    g11 = UIPanGestureRecognizer(target: self, action: #selector(fullScreen.g1Method))

    i.isUserInteractionEnabled = true

    i.addGestureRecognizer(g11)




}



@objc func g1Method(_ sender: UIPanGestureRecognizer){


let tranistioon = sender.translation(in: self.view)
sender.view!.center = CGPoint(x: sender.view!.center.x + tranistioon.x, y: sender.view!.center.y + tranistioon.y)
sender.setTranslation(CGPoint.zero,in: self.view)    }


}

Solution

  • The problem you're running into is that the Storyboard constraints are remaining active with no changes to the constant field of the class object. Here's how to solve it:

    I added two IBOutlet references to the constraints in question on the storyboard:

    @IBOutlet var leadingConstraint: NSLayoutConstraint!
    @IBOutlet var topConstraint: NSLayoutConstraint!
    

    Additionally, right below those constraints, I added a reference for the textField origin like so: var textFieldOrigin = CGPoint.zero

    Finally, I changed the gesture recognizer method to differentiate between the states of the UIPanGestureRecognizer. Here's what I did:

        @objc func g1Method(_ sender: UIPanGestureRecognizer) {
            if sender.state == .began {
                textFieldOrigin = sender.location(in: i)
            } else if sender.state == .ended {
                topConstraint.constant = i.frame.origin.y - i.frame.height
                leadingConstraint.constant = i.frame.origin.x
                topConstraint.isActive = true
                leadingConstraint.isActive = true
            } else {
                let location = sender.location(in: view)
                i.frame.origin = CGPoint(x: location.x - textFieldOrigin.x, y: location.y - textFieldOrigin.y)
                topConstraint.isActive = false
                leadingConstraint.isActive = false
            }
        }
    

    The key points in this code is turning off the constraints, updating their constants, and then turning them back on after the gesture recognizer is complete.