Make a UIButton inactive if no text is entered in a TextField in Swift

Nick89 picture Nick89 · May 13, 2015 · Viewed 9.7k times · Source

So my concept is simple, I have a textfield and a button labelled 'Next'. I would like the Next button to be disabled to users if they have not put anything in the textfield. To do this, I have run this code:

 @IBAction func nextButton(sender: UIButton) {

    if textField.text.isEmpty {

        buttonLabel.userInteractionEnabled = false

    }
 }

This disables the button as i want, but the problem is, if text is then entered in the textfield, the button is still disabled. I have tried adding the "else" statement after the "if" statement to just reverse what i'm saying to see if it works, but it doesn't.

Any help greatly appreciated.

Nick

MY CODE:

import UIKit

class ViewController: UIViewController, UITextFieldDelegate, UIPickerViewDataSource, UIPickerViewDelegate {

func imageEffect() {

    // Set vertical effect for background
    var verticalMotionEffect : UIInterpolatingMotionEffect =
    UIInterpolatingMotionEffect(keyPath: "center.y",
        type: .TiltAlongVerticalAxis)
    verticalMotionEffect.minimumRelativeValue = -20
    verticalMotionEffect.maximumRelativeValue = 20

    // Set horizontal effect for background
    var horizontalMotionEffect : UIInterpolatingMotionEffect =
    UIInterpolatingMotionEffect(keyPath: "center.x",
        type: .TiltAlongHorizontalAxis)
    horizontalMotionEffect.minimumRelativeValue = -20
    horizontalMotionEffect.maximumRelativeValue = 20

    // Create group for background to combine both
    var group : UIMotionEffectGroup = UIMotionEffectGroup()
    group.motionEffects = [horizontalMotionEffect, verticalMotionEffect]

    // Add both effects to your view for background
    myBackgroundView.addMotionEffect(group)

}

var datePickerView:UIDatePicker = UIDatePicker()

@IBAction func textFieldEdited(sender: UITextField) {

    var datePickerView  : UIDatePicker = UIDatePicker()
    datePickerView.datePickerMode = UIDatePickerMode.Date
    sender.inputView = datePickerView
    datePickerView.addTarget(self, action: Selector("handleDatePicker:"), forControlEvents: UIControlEvents.ValueChanged)

    }

func handleDatePicker(sender: UIDatePicker) {
    var dateFormatter = NSDateFormatter()
    dateFormatter.dateFormat = "dd MMMM yyyy"
    questionTextField.text = dateFormatter.stringFromDate(sender.date)
}

var countryData = ["United Kingdom", "France", "Spain", "Germany", "Berlin", "Eygpt", "United States"]

var pickerView:UIPickerView = UIPickerView()

@IBOutlet var progressStatus: UIProgressView!

@IBOutlet var barImage: UIImageView!

@IBOutlet var questionLabel: UILabel!

@IBOutlet var buttonBarImage: UIImageView!

@IBOutlet var buttonLabel: UIButton!

@IBOutlet var myBackgroundView: UIImageView!

@IBOutlet var questionTextField: UITextField!

let questions = ["Where are you going?", "What are you doing there?", "When do you go?"]

var currentQuestionIndex = 0

let placeholder = ["Country", "Activity", "Date"]

var currentPlaceholderIndex = 0

@IBAction func nextButton(sender: AnyObject) {

    if currentQuestionIndex == 0 {

        progressStatus.setProgress(0.333, animated: true)

    } else if currentQuestionIndex == 1 {

        progressStatus.setProgress(0.666, animated: true)

    } else {

        progressStatus.setProgress(1, animated: true)

    }

    // Initial setup on button press
    questionTextField.hidden = false
    barImage.hidden = false
    questionTextField.placeholder = placeholder[currentPlaceholderIndex]
    questionLabel.text = questions[currentQuestionIndex]
    questionTextField.resignFirstResponder()

    // Reset text field to have no text
    questionTextField.text = ""

    // Displays the questions in array and displays the placeholder text in the textfield
    if currentQuestionIndex <= questions.count && currentPlaceholderIndex <= placeholder.count {

        currentQuestionIndex++
        currentPlaceholderIndex++
        //progressStatus.setProgress(0.333, animated: true)
        buttonLabel.setTitle("Next", forState: UIControlState.Normal)


        // Animate text for questionLabel
        UIView.animateWithDuration(1.0, delay: 0.0, usingSpringWithDamping: 0.9, initialSpringVelocity: 0.5, options: nil, animations: {

            self.questionLabel.center = CGPoint(x: -110 , y: 305 + 20)

            }, completion: nil)

    } else {

        //Add some logic here to run whenever the user has answered all the questions.

    }

}


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    questionTextField.delegate = self
    pickerView.delegate = self
    pickerView.dataSource = self

    // Applies the image effect to the image in myBackgroundImage
    imageEffect()

    // Sets the button text
    buttonLabel.setTitle("Get started", forState: UIControlState.Normal)

    // Sets the question text to be blank
    questionLabel.text = ""


    // Sets placeholder text in the text field
    questionTextField.placeholder = ""

    // Hides the text field
    questionTextField.hidden = true

    // Hides the image background for the text field
    barImage.hidden = true

    // Sets the progress bar to nil
    progressStatus.setProgress(0, animated: true)

    if questionTextField.text.isEmpty {

        buttonLabel.userInteractionEnabled = false
    }

}

func textFieldDidBeginEditing(textField: UITextField) {


    buttonLabel.userInteractionEnabled = true


    switch currentQuestionIndex {

    case 0:
        // TODO: Add UIPickerView
        self.view.addSubview(datePickerView)
    case 2:
        // TODO: Add UIDatePicker
        self.view.addSubview(datePickerView)

    default:
        println("default")
    }
}


// resigns the keyboard when user presses the return/next key on keyboard

func textFieldShouldReturn(textField: UITextField) -> Bool {

    questionTextField.resignFirstResponder()

    return true

}

func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {

    return 1
}

func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {

    return countryData.count

}

func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
    return countryData[row]

}

func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {

    questionTextField.text = countryData[row]
    pickerView.hidden = true

}




// Resigns the keyboard if the user presses anywhere on the screen
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {

    self.view.endEditing(true)
}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

}

Answer

Jakub Truhl&#225;ř picture Jakub Truhlář · May 14, 2015

Edit:

Set myButton.userInteractionEnabled = false in the viewDidLoad or viewWillAppear.

Set your textField's delegate.

and then

func textFieldDidBeginEditing(textField: UITextField) {
   if !textField.text.isEmpty
       myButton.enable = true

   } else {
       buttonLabel.enable = false
   }
}