Search code examples
iosuibuttonuipangesturerecognizer

UIButton to not be clickable but to receive gestures


I have a UIButton that I would like to be able to move with a pan gesture, but not be able to click it. What I want is when the user taps the button for the button to not change its appearance as if you just tap a view. Setting isEnabled to false and userInteractionIsEnabled to false result both in the button not receiving the pan events. I can achieve the desired effect with a custom view, but can I do it somehow with the button. Posting code snippet with button creation as requested:

func createAnswerButton() {
    let width : CGFloat = 154
    let height : CGFloat = 60
    let originX = (view.frame.size.width - width) / 2
    let originY = startOverButton.frame.origin.y + collectionView.frame.size.height
    let frame = CGRect(x: originX, y: originY, width: width, height: height)
    let button = UIButton(frame: frame)
    answerButton = button
    button.backgroundColor = .clear
    self.answerButton.setTitleColor(.white, for: .normal)
    let image = UIImage(named: "item_neutral")
    button.setBackgroundImage(image, for: .normal)
    view.addSubview(button)

    let panGesture = UIPanGestureRecognizer(target: self, action: (#selector(MoviesViewController.didPanButton(_:))))
    button.addGestureRecognizer(panGesture)
}

Solution

  • To achieve this, you have to set the adjustsImageWhenHighlighted of the button to false (if you want to do it programatically). In interface builder you can change the button type to custom.

    Here is the code for doing this programatically:

     override func viewDidLoad() {
        super.viewDidLoad()
    
        // Do any additional setup after loading the view.
    
        let width : CGFloat = 154
        let height : CGFloat = 60
        let originX = (view.frame.size.width - width) / 2
        let originY = (view.frame.size.height - width) / 2
        let frame = CGRect(x: originX, y: originY, width: width, height: height)
    
        let button = UIButton(type: .custom)
        button.adjustsImageWhenHighlighted = false
        button.frame = frame
    
        button.addTarget(self, action: #selector(buttonInCodeTapped), for: .touchUpInside)
        button.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(panForButtonInCode(recognizer:))))
        button.setBackgroundImage(UIImage(named: "X"), for: .normal)
        view.addSubview(button)
    }
    

    Here is the result when that property is set to false: enter image description here

    And here is the result when that property is set to true (You can see that when tapped the X gets highlighted):

    enter image description here