How to come back in previous textfield if all textfield is empty? - swift

[if all textfield is fill it will easily come back but if all textfield is empty and i click on last textfield then i want to come back to the previous textfield and so on how i achieved this please help me ]
import UIKit
class OTPVC: CommonViewController,UITextFieldDelegate {
#IBOutlet weak var aboutOtp: UIView!
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var bottomConstraint: NSLayoutConstraint!
#IBOutlet weak var firstOtptxt: UITextField!
#IBOutlet weak var secondOtptxt: UITextField!
#IBOutlet weak var thirdOtptxt: UITextField!
#IBOutlet weak var fourthOtptxt: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
setUpView()
firstOtptxt.delegate = self
secondOtptxt.delegate = self
thirdOtptxt.delegate = self
fourthOtptxt.delegate = self
}
private func setUpView() {
aboutOtp.makeCornerRadius(10)
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if ((textField.text?.count)!) < 1 && (string.count > 0) {
if textField == firstOtptxt{
secondOtptxt.becomeFirstResponder()
}
if textField == secondOtptxt {
thirdOtptxt.becomeFirstResponder()
}
if textField == thirdOtptxt {
fourthOtptxt.becomeFirstResponder()
}
if textField == fourthOtptxt {
fourthOtptxt.becomeFirstResponder()
}
textField.text = string
return false
} else if (((textField.text?.count)!) >= 1) && (string.count == 0) {
if textField == secondOtptxt {
firstOtptxt.becomeFirstResponder()
}
if textField == thirdOtptxt {
secondOtptxt.becomeFirstResponder()
}
if textField == fourthOtptxt {
thirdOtptxt.becomeFirstResponder()
}
if textField == firstOtptxt {
firstOtptxt.becomeFirstResponder()
}
textField.text = string
return false
}
else if ((textField.text?.count)!) >= 1 {
textField.text = string
return false
}
return true
}
}
[if all textfield is fill it will easily come back but if all textfield is empty and i click on last textfield then i want to come back to the previous textfield and so on how i achieved this please help me ]
[if all textfield is fill it will easily come back but if all textfield is empty and i click on last textfield then i want to come back to the previous textfield and so on how i achieved this please help me ]

protocol MyTextFieldDelegate: UITextFieldDelegate {
func textField(_ textField: UITextField, didDeleteBackwardAnd wasEmpty: Bool)
}
class MyTextField: UITextField {
override func deleteBackward() {
// see if text was empty
let wasEmpty = text == nil || text! == ""
// then perform normal behavior
super.deleteBackward()
// now, notify delegate (if existent)
(delegate as? MyTextFieldDelegate)?.textField(self, didDeleteBackwardAnd: wasEmpty)
}
}
[just put a delegate method and its work fine in my project yippy]

there is a trick, you can have a 'space' in your textfields, so that problem will be solved .

Related

How do I add a placeholder to my UITextField? (Using Xcode 12)

EDIT: New ErrorCurrently using XCode 12, and I'm trying to add a placeholder. I followed the Swift QuestionBot documentation but it doesn't work (I'm assuming it's because my XCode is much newer). Anyway, appreciate all the help!
EDIT: I added an image of a new error I got.
EDIT 2: Added MyQuestionAnswerer() struct! It's on a different view controller (obvious).
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var responseLabel: UILabel!
#IBOutlet weak var askButton: UIButton!
#IBOutlet weak var questionField: UITextField!
let questionAnswerer = MyQuestionAnswerer()
override func viewDidLoad() {
super.viewDidLoad()
questionField.becomeFirstResponder()
}
func respondToQuestion(_ question: String) {
let answer = questionAnswerer.responseTo(question: question)
displayAnswerTextOnScreen(answer)
questionField.placeholder = "Ask another question..."
questionField.text = nil
askButton.isEnabled = false
}
#IBAction func askButtonTapped(_ sender: AnyObject) {
guard questionField.text != nil else {
return
}
questionField.resignFirstResponder()
}
func displayAnswerTextOnScreen(_ answer: String) {
responseLabel.text = answer
}
}
extension ViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return false
}
func textFieldDidEndEditing(_ textField: UITextField) {
guard let text = textField.text else {
return
}
respondToQuestion(text)
}
#IBAction func editingChanged(_ textField: UITextField) {
guard let text = textField.text else {
askButton.isEnabled = false
return
}
askButton.isEnabled = !text.isEmpty
}
}
struct MyQuestionAnswerer {
func responseTo(question: String) -> String {
let loweredQuestion = question.lowercased()
if loweredQuestion == "What is the current vaccination rate of the Philippines?" {
return "As of August 8, the vaccination rate of the Philippines is 10%!"
} else if loweredQuestion.hasPrefix("Where") {
return "Check the map for nearby vaccination centers."
}
}
The placeholder is not present when the textFiled as it is not set until the respondToQuestion method is called. It should probably be set inside of a view controller life cycle method such as viewDidLoad().
Example:
override func viewDidLoad() {
super.viewDidLoad()
questionField.placeholder = "Ask another question"
questionField.becomeFirstResponder()
}

Swift How to disable a TextField while another UITextField is highlighted or has value

I have three text fields: tempTextField, airPressureTextField, and airDensityTextField. I want to create a check between Textfields to get the following logic:
If tempTextField or airPressureTextField is in focus where user trying to enter a value or user enters value and returns, I want to disable airDensityTextField. I tried this code. It disables airDensityTextField correctly. But If I remove the focus from tempTextField or airPressureTextField and empty both those two textfields, the airDensityTextField is still disabled.
func textFieldDidEndEditing(_ textField: UITextField) {
if let t = tempTextField.text, let ap = airPressureTextField.text {
airDensityTextField.isEnabled = false
} else {
airDensityTextField.isEnabled = true
}
}
I tried the code in both textFieldDidEndEditing and textFieldDidBeginEditing, the result is the same.
How can I make it work?
You can see which textfield is editing inside textFieldDidBeginEditing and disable airDensityTextField. Then, when they finish editing, you need to check if the text is "" (blank) in addition to whether it's nil or not.
class TextFieldVC: UIViewController, UITextFieldDelegate {
#IBOutlet weak var tempTextField: UITextField!
#IBOutlet weak var airPressureTextField: UITextField!
#IBOutlet weak var airDensityTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
tempTextField.delegate = self
airPressureTextField.delegate = self
airDensityTextField.delegate = self
}
func textFieldDidBeginEditing(_ textField: UITextField) {
switch textField {
case tempTextField:
airDensityTextField.isEnabled = false
case airPressureTextField:
airDensityTextField.isEnabled = false
default:
break
}
}
func textFieldDidEndEditing(_ textField: UITextField) {
if
let tempText = tempTextField.text,
let apText = airPressureTextField.text,
tempText != "" || apText != "" /// check if at least one of them has text
{
airDensityTextField.isEnabled = false
} else {
airDensityTextField.isEnabled = true
}
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return false
}
}

How can I append text to the active UITextField - Swift

I'm trying to make a custom keyboard. But I cannot input info on the active textField. I'm not sure what I'm doing wrong.
PS: The keyboard is in another ViewController and is passing the sender.tag well.
Here is my code:
import UIKit
class HomeVC: UIViewController, ButtonTapDelegate, UITextFieldDelegate {
#IBOutlet var textField1: UITextField!
#IBOutlet var textField2: UITextField!
#IBOutlet var keyboardView: UIView!
var activeField: UITextField?
var delegate: ButtonTapDelegate!
override func viewDidLoad() {
addKeyboard(view: keyboardView)
textField1.inputView = UIView()
textField2.inputView = UIView()
textField1.becomeFirstResponder()
activeField?.delegate = self
}
func textFieldDidBeginEditing(_ textField: UITextField) {
activeField = textField
}
func addKeyboard(view: UIView) {
let keyboard = KeyboardVC(nibName: "KeyboardVC", bundle: nil)
keyboard.delegate = self
view.addSubview(keyboard.view)
addChild(keyboard)
}
func didTapButton(sender: UIButton) {
if sender.tag == 8 {
activeField?.text?.append(contentsOf: " ")
} else if sender.tag == 9 {
activeField?.text?.removeAll()
} else {
let val = sender.titleLabel?.text
activeField?.text?.append(contentsOf: val!)
}
}
}
There is a slight problem in your code that is causing your issue. In the comments, you mentioned that didTapButton() is called beforetextFieldDidBeginEditing. This means that actionField is not assigned a value and therefore is nil. Your code in didTapButton() safely unwraps the optional value so that no error is produced, but of course, you cannot append text to a non-existent UITextField.
I was able to fix it after some research with changes to the textFieldDidBeginEditing and didTapButton functions: Here is the full code if anybody wants to choose one textField at a time with a custom keyboard:
import UIKit
class HomeVC: UIViewController, ButtonTapDelegate, UITextFieldDelegate {
#IBOutlet var textField1: UITextField!
#IBOutlet var textField2: UITextField!
#IBOutlet var keyboardView: UIView!
var activeField: UITextField?
var delegate: ButtonTapDelegate!
override func viewDidLoad() {
addKeyboard(view: keyboardView)
textField1.inputView = UIView()
textField2.inputView = UIView()
textField1.becomeFirstResponder()
activeField?.delegate = self
}
func textFieldDidBeginEditing(_ textField: UITextField) {
self.activeField = textField
}
func addKeyboard(view: UIView) {
let keyboard = KeyboardVC(nibName: "KeyboardVC", bundle: nil)
keyboard.delegate = self
view.addSubview(keyboard.view)
addChild(keyboard)
}
func didTapButton(sender: UIButton) {
if textField1 == self.activeField {
if sender.tag == 8 {
textField1.text?.append(contentsOf: " ")
} else if sender.tag == 9 {
textField1.text?.removeAll()
} else {
let val = sender.titleLabel?.text?
textField1.text?.append(contentsOf: val!)
}
return;
}
if textField2 == self.activeField {
if sender.tag == 8 {
textField2.text?.append(contentsOf: " ")
} else if sender.tag == 9 {
textField2.text?.removeAll()
} else {
let val = sender.titleLabel?.text?
textField2.text?.append(contentsOf: val!)
}
return;
}
}
}

the button is disabled when text view is empty else is enabled

I'm developing note app, when the text view is empty the done button should be disabled so user could not be able to save empty notes into data base, else the button should be enabled.
here's my code below, my attempts have failed; how I can solve this problem?
#IBOutlet weak var textView: UITextView!
#IBOutlet weak var done: UIBarButtonItem!
override func viewDidLoad() {
super.viewDidLoad()
title = note?.text
if (self.textView.text.isEmpty){
done.enabled = false
}
if let noteContent = note
{
textView.text = noteContent.text
}
self.navigationController!.toolbarHidden = false;
}
func textViewShouldBeginEditing(textView: UITextView) -> Bool{
done.enabled = true
return done.enabled
}
Make your view controller conform to UITextViewDelegate protocol
In Interface Builder, connect the delegate on the text view to your view controller.
Add the following function to your view controller:
func textViewDidChange(textView: UITextView) {
if textView == self.textView {
self.doneButton.enabled = !textView.text.isEmpty
}
}
Try to use another delegate method for you're purpose. This is example :
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var button: UIButton!
#IBOutlet weak var textView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
textView.delegate = self
if (textView.text.isEmpty) {
button.enabled = false
}
}
}
extension ViewController: UITextViewDelegate {
func textView(textView: UITextView, range: NSRange, replacementText text: String) -> Bool
{
if (!textView.text.isEmpty) {
button.enabled = true
} else {
button.enabled = false
}
return true
}
}
Try this in textViewDidChange method:
yourBarButtonItem.isEnabled = !(yourTextField.text?.isEmpty ?? false)

Swift: Button Enabling Not Working?

I have a button that is disabled in my view controller. I have IBActions for when two text fields are edited. I am trying to enable the button when two text fields both contain integers. I have tried to do this, but whenever I run the ios simulator, the button stays disabled even when I put integers into each text field. Why is it staying disabled? I am new to swift, so please help me out. Here is the code for my entire project:
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var calculatorButton: UIButton!
#IBOutlet weak var inspirationLabel: UILabel!
#IBOutlet weak var beginningLabel: UILabel!
#IBOutlet weak var calculatorContainer: UIView!
#IBOutlet weak var answer1Label: UILabel!
#IBOutlet weak var doneButton: UIButton!
#IBOutlet weak var yourWeightTextField: UITextField!
#IBOutlet weak var calorieNumberTextField: UITextField!
#IBOutlet weak var menuExampleButton: UIButton!
#IBOutlet weak var aboutButton: UIButton!
#IBOutlet weak var calculateButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib
yourWeightTextField.delegate = self
calorieNumberTextField.delegate = self
calculateButton.enabled = false
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func calculatorButtonTapped(sender: AnyObject) {
calculatorContainer.hidden = false
inspirationLabel.hidden = true
beginningLabel.hidden = true
menuExampleButton.hidden = true
aboutButton.hidden = true
}
#IBAction func yourWeightEditingDidEnd(sender: AnyObject) {
yourWeightTextField.resignFirstResponder()
}
#IBAction func calorieNumberEditingDidEnd(sender: AnyObject) {
calorieNumberTextField.resignFirstResponder()
}
var yourWeightFilled = false
var calorieNumberFilled = false
func yourWeightTextFieldValueValidInt(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
// Find out what the text field will be after adding the current edit
let text = (yourWeightTextField.text as NSString).stringByReplacingCharactersInRange(range, withString: string)
if let intVal = text.toInt() {
self.yourWeightFilled = true
} else {
self.yourWeightFilled = false
}
return true
}
func calorieNumberTextFieldValueValidInt(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
// Find out what the text field will be after adding the current edit
let text = (calorieNumberTextField.text as NSString).stringByReplacingCharactersInRange(range, withString: string)
if let intVal = text.toInt() {
self.calorieNumberFilled = true
} else {
self.calorieNumberFilled = false
}
return true
}
#IBAction func yourWeightTextFieldEdited(sender: AnyObject) {
if self.yourWeightFilled && self.calorieNumberFilled {
self.calculateButton.enabled = true
}
}
#IBAction func calorieNumberTextFieldEdited(sender: AnyObject) {
if self.yourWeightFilled && self.calorieNumberFilled {
self.calculateButton.enabled = true
}
}
}
Your delegate methods are a bit mixed up -- they have to be named exactly what the caller expects, or they won't be found, so yourWeightTextFieldValueValidInt() and calorieNumberTextFieldValueValidInt() aren't being called at all. Instead you'll need to handle the edits to both text fields in a single method:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
// Find out what the text field will be after adding the current edit
let text = (textField.text as NSString).stringByReplacingCharactersInRange(range, withString: string)
if textField == yourWeightTextField {
yourWeightFilled = text.toInt() != nil
} else if textField == calorieNumberTextField {
calorieNumberFilled = text.toInt() != nil
}
return true
}