112

I want to disable a button (UIButton) on iOS after it is clicked. I am new to developing for iOS but I think the equivalent code on objective - C is this:

button.enabled = NO;

But I couldn't do that on swift.

Léo Natan
  • 56,823
  • 9
  • 150
  • 195
baranbaris
  • 1,281
  • 2
  • 8
  • 12

11 Answers11

231

The boolean value for NO in Swift is false.

button.isEnabled = false

should do it.

Here is the Swift documentation for UIControl's isEnabled property.

KerrM
  • 5,139
  • 3
  • 35
  • 60
  • It's the same whether you created the button via its initializer or via storyboards. – KerrM Nov 28 '18 at 16:45
  • I meant when I have no outlet. Anyhow the solution is to define the button globally. –  Nov 28 '18 at 19:08
48

If you want the button to stay static without the "pressed" appearance:

// Swift 2
editButton.userInteractionEnabled = false 

// Swift 3
editButton.isUserInteractionEnabled = false 

Remember:

1) Your IBOutlet is --> @IBOutlet weak var editButton: UIButton!

2) Code above goes in viewWillAppear

Mick
  • 30,759
  • 16
  • 111
  • 130
Daviiid
  • 629
  • 5
  • 10
  • 1
    I thought this was exactly what I was looking for, but this appears to be UIKit only, not AppKit. – drootang Dec 21 '16 at 15:39
14

The way I do this is as follows:

@IBAction func pressButton(sender: AnyObject) {
    var disableMyButton = sender as? UIButton
    disableMyButton.enabled = false
}

The IBAction is connected to your button in the storyboard.

If you have your button setup as an Outlet:

    @IBOutlet weak var myButton: UIButton!

Then you can access the enabled properties by using the . notation on the button name:

    myButton.enabled = false
Krivvenz
  • 3,911
  • 3
  • 22
  • 32
  • Works fine for me in Swift 4. I noticed by default it sets the sender to Any instead of AnyObject but both still work.... What error are you getting? – Krivvenz Feb 05 '19 at 14:08
  • For clarity, perhaps you should state in your answer above that the IBOutlet is required for your code to work. Whether or not the IBOutlet was needed is what confused me. Clearly, it is needed. –  Feb 06 '19 at 00:10
  • It's not required for it to work. You can type cast the button in the IBAction and change the enabled status or if you have it set up as an IBOutlet you can do it using the .notation on the outlet. Both ways work. – Krivvenz Mar 07 '19 at 16:28
  • I do believe that the IBOutlet is needed if you are to disable the button from within another function. –  Mar 10 '19 at 02:05
8

Disable a button on Swift 3:

yourButton.isEnabled = false
Gilad Brunfman
  • 3,452
  • 1
  • 29
  • 29
8

For those who Googled "disable a button" but may have more nuanced use cases:

Disable with visual effect: As others have said, this will prevent the button from being pressed and the system will automatically make it look disabled:

yourButton.isEnabled = false 

Disable without visual effect: Are you using a button in a case where it should look normal but not behave likes button by reacting to touches? Try this!

yourButton.userInteractionEnabled = false

Hide without disabling: This approach hides the button without disabling it (invisible but can still be tapped):

 yourButton.alpha = 0.0

Remove: This will remove the view entirely:

 yourButton.removeFromSuperView()

Tap something behind a button: Have two buttons stacked and you want the top button to temporarily act like it's not there? If you won't need the top button again, remove it. If you will need it again, try condensing its height or width to 0!

Dave G
  • 12,042
  • 7
  • 57
  • 83
4

Swift 5 / SwiftUI

Nowadays it's done like this.

Button(action: action) {
  Text(buttonLabel)
}
  .disabled(!isEnabled)
Viktor Sec
  • 2,756
  • 1
  • 24
  • 31
3

You can enable/disable a button using isEnabled or isUserInteractionEnabled property.

The difference between two is :

  • isEnabled is a property of UIControl (super class of UIButton) and it has visual effects (i.e. grayed out) of enable/disable

  • isUserInteractionEnabled is a property of UIView (super class of UIControl) and has no visual effect although but achieves the purpose

Usage :

myButton.isEnabled = false // Recommended approach

myButton.isUserInteractionEnabled = false // Alternative approach
Jayprakash Dubey
  • 35,723
  • 18
  • 170
  • 177
  • Do you know why I am getting this error? `Value of type '(AnyObject) -> ()' has no member 'isEnabled'` –  Feb 05 '19 at 04:23
  • I also get an error if I change `(_ sender: )` to `UIButton` . The error reads: `Value of type '(UIButton) -> ()' has no member 'isEnabled'` –  Feb 05 '19 at 04:25
0

The button can be Disabled in Swift 4 by the code

@IBAction func yourButtonMethodname(sender: UIButon) {
 yourButton.isEnabled = false 
}
Tina Detroja
  • 124
  • 6
  • If you try your code this error should occur: `Value of type '(AnyObject) -> ()' has no member 'isEnabled'` –  Feb 05 '19 at 04:22
  • I think you mean `yourButton(sender: UIButton)`. Your updated code will likely cause the following error: `Value of type '(UIButton) -> ()' has no member 'isEnabled'` –  Feb 05 '19 at 07:02
0

Let's say in Swift 4 you have a button set up for a segue as an IBAction like this @IBAction func nextLevel(_ sender: UIButton) {} and you have other actions occurring within your app (i.e. a timer, gamePlay, etc.). Rather than disabling the segue button, you might want to give your user the option to use that segue while the other actions are still occurring and WITHOUT CRASHING THE APP. Here's how:

var appMode = 0

@IBAction func mySegue(_ sender: UIButton) {

    if appMode == 1 {  // avoid crash if button pressed during other app actions and/or conditions
        let conflictingAction = sender as UIButton
        conflictingAction.isEnabled = false
    }
}

Please note that you will likely have other conditions within if appMode == 0 and/or if appMode == 1 that will still occur and NOT conflict with the mySegue button. Thus, AVOIDING A CRASH.

0

in order for this to work:

yourButton.isEnabled = false

you need to create an outlet in addition to your UI button.

Ionass
  • 3
  • 2
0

Building on other answers here. I wanted to disable button for a few seconds to prevent double taps. Swift 5 version, xcode 13.4.1 likes this and has no warnings or errors.

@IBAction func saveComponent(_ sender: Any) {
  let myButton = sender as? UIButton
  myButton?.isEnabled = false
    
  DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(2000)) 
  {
    myButton?.isEnabled = true
  }
}
Mike Volmar
  • 1,927
  • 1
  • 22
  • 31