Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.
}

}
like image 421
Nick89 Avatar asked May 13 '15 21:05

Nick89


People also ask

How check TextField is empty or not in Swift?

Basic Swift Code for iOS Apps Follow the below steps. Step 2 − Open Main. storyboard add one textField, one button and one label one below other as shown in the figure. On click of the button we will check whether the text field is empty or not and show the result in label.

Which is the correct way to disable UIButton through programmatically?

In this Swift code example, you will learn how to disable UIButton. The quickest way to disable the button in Swift is to simply set the button's isEnabled property to false. For example button. isEnabled = false.

How do I disable TextField editing in Swift?

Set the Boolean variable to false, which enables editing in the text field. When someone taps the Done button, isEditing becomes false. Set the Boolean variable to true, which disables editing in the text field.

How do I restrict TextField to numbers only in Swift?

Select the text field that you want to restrict to numeric input. Go to its attribute inspector. Select the keyboard type and choose number pad from there.


3 Answers

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
   }
}
like image 152
Jakub Truhlář Avatar answered Sep 21 '22 17:09

Jakub Truhlář


You have to set your VC as the TextFieldDelegate. So you can react on the textfields state. See this little example class:

class ViewController: UIViewController, UITextFieldDelegate {

  @IBOutlet weak var myTextField: UITextField!
  @IBOutlet weak var myButton: UIButton!

  override func viewDidLoad() {
    super.viewDidLoad()

    // Set the delegate of your textField to this class
    myTextField.delegate = self

    if myTextField.text.isEmpty {
      myButton.userInteractionEnabled = false
    }
  }
  // This method is available, because this class is now the delegate
  func textFieldDidBeginEditing(textField: UITextField) {
    myButton.userInteractionEnabled = true
  }
}

This should be quite similar to your VC.

Please note the first line, where the VC is told to conform to the TextFieldDelegate Protocol.

like image 21
gutenmorgenuhu Avatar answered Sep 21 '22 17:09

gutenmorgenuhu


Your code should look some thing similar like below, Assuming Next button should be enabled only when we have text in one text field else you need to change the logic accordingly.

class ViewController: UIViewController, UITextFieldDelegate {

@IBOutlet weak var textField1: UITextField!
@IBOutlet weak var textField2: UITextField!
@IBOutlet weak var textField3: UITextField!
@IBOutlet weak var nextButton: UIButton!

override func viewDidLoad() {
    super.viewDidLoad()
    nextButton.userInteractionEnabled = false
    textField1.delegate = self
    textField2.delegate = self
    textField3.delegate = self
}
@IBAction func NextButtonAction(sender: UIButton)
{
    println("Next Button Tapped")
}
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    if textField == textField1
    {
        var oldStr = textField1.text as NSString
        var newStr = oldStr.stringByReplacingCharactersInRange(range, withString: string) as NSString
        if newStr.length == 0
        {
            nextButton.userInteractionEnabled = false
        }else
        {
            nextButton.userInteractionEnabled = true
        }
    }
    return true
}
}
like image 37
Shiva Kumar Avatar answered Sep 22 '22 17:09

Shiva Kumar