Drag UIButton without it shifting to center [Swift 3]

前端 未结 1 1115
渐次进展
渐次进展 2020-12-10 20:37

So I found out how to make a button draggable using the UIPanGestureRecognizer. But the only way I know how to do it is by storing and dragging the button by the center. The

相关标签:
1条回答
  • 2020-12-10 21:09

    This can be done at least in two different ways, one using GestureRecognizer your question way and other way is subclassing the UIView and implementing the touchesBegan, touchesMoved , touchesEnded, touchesCancelled in general will work for any UIView subclass can be UIButton or UILabel or UIImageView etc...

    In your way, using GestureRecognizer I make a few changes you still require a var to keep the origin CGPoint of the touch in your UIButton so we get the touch position relative to the UIButton and when the drag continue adjust the UIButton origin according to the origin touch position and the positions of the movement

    Method 1 GestureRecognizer

    import UIKit
    
    class ViewController: UIViewController {
    
        @IBOutlet weak var button: UIButton!
        var buttonOrigin : CGPoint = CGPoint(x: 0, y: 0)
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
            let gesture = UIPanGestureRecognizer(target: self, action: #selector(buttonDrag(pan:)))
            self.button.addGestureRecognizer(gesture)
        }
    
        func buttonDrag(pan: UIPanGestureRecognizer) {
            print("Being Dragged")
            if pan.state == .began {
                print("panIF")
                buttonOrigin = pan.location(in: button)
            }else {
                print("panELSE")
                let location = pan.location(in: view) // get pan location
                button.frame.origin = CGPoint(x: location.x - buttonOrigin.x, y: location.y - buttonOrigin.y)
            }
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
    
    }
    

    Method 2 UIView subclass in this case UIButton subclass

    Use this UIButton subclass

    import UIKit
    
    class DraggableButton: UIButton {
    
        var localTouchPosition : CGPoint?
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
        }
    
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            super.touchesBegan(touches, with: event)
            let touch = touches.first
            self.localTouchPosition = touch?.preciseLocation(in: self)
        }
    
        override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesMoved(touches, with: event)
        let touch = touches.first
        guard let location = touch?.location(in: self.superview), let localTouchPosition = self.localTouchPosition else{
            return
        }
    
        self.frame.origin = CGPoint(x: location.x - localTouchPosition.x, y: location.y - localTouchPosition.y)
        }
    
        override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
            super.touchesEnded(touches, with: event)
            self.localTouchPosition = nil
        }
    
        override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
            super.touchesCancelled(touches, with: event)
            self.localTouchPosition = nil
        }
    
    }
    

    Result

    Hope this helps you

    0 讨论(0)
提交回复
热议问题