Help me, plz!
I can't not hide keyboard when changing one to another TextField.
I click on the "user" textfield pop-up Picker , click on a "Password" textfield , a pop-up keyboard, but if you click again on the "User" is not hide keyboard.
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
userNameTextField.resignFirstResponder()
userPasswordTextField.resignFirstResponder()
}
func textFieldDidBeginEditing(textField: UITextField) {
if textField == userNameTextField {
pickerUser.hidden = false
print("userNameTextField")
} else {
pickerUser.hidden = true
print("#userPasswordTextField")
}
}
#IBAction func userNameTextFieldStartEdit(sender: AnyObject) {
userNameTextField.resignFirstResponder()
userPasswordTextField.resignFirstResponder()
pickerUser.hidden = false
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
Use this Code,
func textFieldDidBeginEditing(textField: UITextField) {
if textField == userNameTextField {
pickerUser.hidden = false
print("userNameTextField")
self.view.endEditing(true)
} else {
pickerUser.hidden = true
print("#userPasswordTextField")
}
}
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
if(textField == userNameTextField) {
self.view.endEditing(true)
return true
}
return true
}
its working for me, hope its helpful
tyr only one line add in below:
func textFieldDidBeginEditing(textField: UITextField) {
if textField == userNameTextField {
textField.resignFirstResponder() // this line add
pickerUser.hidden = false
print("userNameTextField")
} else {
pickerUser.hidden = true
print("#userPasswordTextField")
}
}
I think it's that function you should call to hide your keyboard :
func textFieldShouldReturn(textField: UITextField) -> Bool
{
textField.resignFirstResponder()
return true
}
Instead of your pickerUser.hidden = true
And also:
class ViewController: UIViewController, UITextFieldDelegate {
(Do you have that one ?)
Related
I want to hide keyboard before move to next controller. Also implement self.view.enditing(true) in viewWillDisapear . But keybard not hide how to hide this?
func textFieldDidBeginEditing(_ textField: UITextField) {
if textField == tagTxt{
self.view.endEditing(true)
textField.resignFirstResponder()
let interstControlle = self.storyboard?.instantiateViewController(withIdentifier: "InterestViewController") as! InterestViewController
interstControlle.PContId = "InterestViewController"
interstControlle.delegate = self
if tagsID.count > 0{
interstControlle.PTagsID = tagsID
}
self.navigationController?.pushViewController(interstControlle, animated: true)
}
}
Use this:
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
if textField == tagTxt{
return NO;
}
return YES;
}
Swift 3:
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
if textField == tagTxt{
return false
}
return true
}
You have to return false before textfield get active. We can see difference by name textFieldShouldBeginEditing and textFieldDidBeginEditing.
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
if textField == tagTxt {
//Your code to move in next view
return false
}
return true
}
I have outlets to 3 textfields in my code as follows :
#IBOutlet var oldPasswordTextField: UITextField! { didSet { oldPasswordTextField.delegate = self } }
#IBOutlet var newPasswordTextField: UITextField! { didSet { newPasswordTextField.delegate = self } }
#IBOutlet var confirmPasswordTextField: UITextField! { didSet { confirmPasswordTextField.delegate = self } }
In my textFieldShouldReturn delegate method, I want to make the next textfield as the first responder on click of return as follows :
func textFieldShouldReturn(textField: UITextField) -> Bool { //delegate method
textField.resignFirstResponder()
if textField == oldPasswordTextField
{
newPasswordTextField.becomeFirstResponder()
}
else if textField == newPasswordTextField
{
confirmPasswordTextField.becomeFirstResponder()
}
else
{
saveButtonTapped()
}
return true
}
But it wasn't working. So I tried to check what was going wrong. So I tried this :
func textFieldShouldReturn(textField: UITextField) -> Bool { //delegate method
if textField.canResignFirstResponder()
{
print("textField can resign first responder")
if textField.resignFirstResponder() == true
{
print("textField resigned first responder")
}
else
{
print("textField didnt resign first responder")
}
}
else
{
print("textField cant resign first responder")
}
if textField == oldPasswordTextField
{
if newPasswordTextField.canBecomeFirstResponder() == true
{
if newPasswordTextField.becomeFirstResponder() == true
{
print("newPassword field has become first responder")
}
else
{
print("newPassword field cannot become first responder")
}
}
}
else if textField == newPasswordTextField
{
confirmPasswordTextField.becomeFirstResponder()
}
else
{
saveButtonTapped()
}
return true
}
And overtime I get "textField cant resign first responder"
"newPassword field cannot become first responder"
on my console. I don't know whats going wrong here. Why are the canResignFirstResponder() method and becomeFirstResponder() methods returning false? Any help?
Try to use tags in your text fields. This worked for me:
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
NSInteger nextTag = textField.tag + 1;
// Try to find next responder
UIResponder* nextResponder = [textField.superview viewWithTag:nextTag];
if (nextResponder) {
// Found next responder, so set it.
[nextResponder becomeFirstResponder];
} else {
// Not found, so remove keyboard.
[textField resignFirstResponder];
}
return NO; // We do not want UITextField to insert line-breaks.
}
Sorry I didn't see it wasn't Objective-C, in swift it would be:
func textFieldShouldReturn(textField: UITextField!) -> Bool {
let nextTag:Int = textField.tag + 1
// Try to find next responder
if let nextResponder: UIResponder! = textField.superview!.viewWithTag(nextTag){
nextResponder.becomeFirstResponder()
} else {
// Not found, so remove keyboard.
textField.resignFirstResponder()
}
return false; // We do not want UITextField to insert line-breaks.
}
I found the solution here: Switching between Text fields on pressing return key in Swift
Got it. The above code is fine. The mistake in my code was that my 'textFieldShouldEndEditing' method was returning false which was why my resignFirstResponder method was returning false and it wasn't working.
So I made the 'textFieldShouldEndEditing' method return true and it works fine. :)
func textFieldShouldEndEditing(textField: UITextField) -> Bool { //delegate method
return true
}
func textFieldDidBeginEditing(textField: UITextField) {
scrlView.setContentOffset(CGPointMake(0, textField.frame.origin.y-70), animated: true)
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
scrlView .setContentOffset(CGPointMake(0, 0), animated: true)
return true
}
How can I move cursor from one textfield to another automatically after entering value in the first textfield?
first, you need add tags to your text fields orderly
func textFieldShouldReturn(textField: UITextField) -> Bool {
let nextTag = textField.tag + 1;
// Try to find next responder
var nextResponderTxt: UITextField!
nextResponderTxt = textField.superview?.viewWithTag(nextTag) as? UITextField
if ((nextResponderTxt) != nil) {
// Found next responder, so set it.
nextResponderTxt.becomeFirstResponder()
} else {
// Not found, so remove keyboard.
textField.resignFirstResponder()
}
return false; // We do not want UITextField to insert line-breaks.
}
Also you can change the return key to next
I have four textFields and each takes only one character, similar to the lock screen. I can input and move from one textField to next textField.
Problem is when I want to delete and move to previous textField, I don't know when the delete button is clicked.
I'm using:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
to input and move from one textField to another.
How do I know when the delete key is pressed?
edit/update:
Xcode 11 • Swift 5.2 or later
Follow up on this question and Swift 5 syntax can be found on this post
Original answer
Swift 1.x
Following up Istvan answer, you need to post a notification when the deleteBackward is pressed:
class DigitField: UITextField {
override func deleteBackward() {
super.deleteBackward()
NSNotificationCenter.defaultCenter().postNotificationName("deletePressed", object: nil)
}
}
Then inside viewDidLoad() you add an observer as follow:
NSNotificationCenter.defaultCenter().addObserver(self, selector: "goPrevious", name: "deletePressed", object: nil)
and your method:
func goPrevious() {
if secondDigit.isFirstResponder() {
secondDigit.enabled = false
firstDigit.enabled = true
firstDigit.becomeFirstResponder()
} else if thirdDigit.isFirstResponder() {
thirdDigit.enabled = false
secondDigit.enabled = true
secondDigit.becomeFirstResponder()
} else if fourthDigit.isFirstResponder() {
fourthDigit.enabled = false
thirdDigit.enabled = true
thirdDigit.becomeFirstResponder()
}
}
Select your text field and connect it to your DigitField
You need to connect each text field to an IBAction (using sent events editing changed)
The view controller code should look like this:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var firstDigit: UITextField!
#IBOutlet weak var secondDigit: UITextField!
#IBOutlet weak var thirdDigit: UITextField!
#IBOutlet weak var fourthDigit: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "goPrevious", name: "deletePressed", object: nil)
firstDigit.secureTextEntry = true
secondDigit.secureTextEntry = true
thirdDigit.secureTextEntry = true
fourthDigit.secureTextEntry = true
firstDigit.keyboardType = .DecimalPad
secondDigit.keyboardType = .DecimalPad
thirdDigit.keyboardType = .DecimalPad
fourthDigit.keyboardType = .DecimalPad
firstDigit.becomeFirstResponder()
secondDigit.enabled = false
thirdDigit.enabled = false
fourthDigit.enabled = false
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func goPrevious() {
if secondDigit.isFirstResponder() {
secondDigit.enabled = false
firstDigit.enabled = true
firstDigit.becomeFirstResponder()
} else if thirdDigit.isFirstResponder() {
thirdDigit.enabled = false
secondDigit.enabled = true
secondDigit.becomeFirstResponder()
} else if fourthDigit.isFirstResponder() {
fourthDigit.enabled = false
thirdDigit.enabled = true
thirdDigit.becomeFirstResponder()
}
}
// You need to connect each text field to an IBAction (using sent events editing changed) –
#IBAction func firstChanged(sender: UITextField) {
if let digitOne = sender.text.toInt() {
println(digitOne)
sender.enabled = false
secondDigit.enabled = true
secondDigit.becomeFirstResponder()
} else {
sender.text = ""
}
}
#IBAction func secondChanged(sender: UITextField) {
if let digitTwo = sender.text.toInt() {
println(digitTwo)
sender.enabled = false
thirdDigit.enabled = true
thirdDigit.becomeFirstResponder()
} else {
sender.text = ""
}
}
#IBAction func thirdChanged(sender: UITextField) {
if let digitThree = sender.text.toInt() {
println(digitThree)
sender.enabled = false
fourthDigit.enabled = true
fourthDigit.becomeFirstResponder()
} else {
sender.text = ""
}
}
#IBAction func fourthChanged(sender: UITextField) {
if let digitFour = sender.text.toInt() {
println(digitFour)
sender.enabled = false
} else {
sender.text = ""
}
}
}
Subclass UITextField as follows:
import UIKit
class MyTextField: UITextField {
override func deleteBackward() {
super.deleteBackward()
println("Delete button was tapped")
}
}
Then change the class of your text field to MyTextField. That should do it!
There is a possible solution in this answer to a similar question. You can subclass your UITextField and then override this method in your subclass:
(BOOL)keyboardInputShouldDelete:(UITextField *)textField
Event this code is in Objective-C, it should show you the proper use of this method.
Use replacementString in function to know whats happening in UItextField
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if (string.length == 0) {
//delete
} else {
//any other key
}
return YES;
}
I hope my answer will help you:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
let char = string.cStringUsingEncoding(NSUTF8StringEncoding)!
let isBackSpace = strcmp(char, "\\b")
if (isBackSpace == -92) {
println("Backspace was pressed")
}
return true
}
When the user presses next on the keypad I want to move from the current UITextField to the next UITextField, the UIReturnKeyType is set to UIReturnKeyType.Next
Here is how I have the UITextField set up.
username.returnKeyType = UIReturnKeyType.Next
username.textColor = UIColor.whiteColor()
username.placeholder = "Username"
username.borderStyle = UITextBorderStyle.RoundedRect
uUsername.textAlignment = NSTextAlignment.Center
username.backgroundColor = UIColor.lightGrayColor()
username.font = UIFont(name: "Avenir Next", size: 14)
username.autocapitalizationType = UITextAutocapitalizationType.None
username.autocorrectionType = UITextAutocorrectionType.No
You have to configure the UITextFieldDelegate method textFieldShouldReturn:. From within this method, you can check which text field is returning and reassign first responder status accordingly. Of course this mean you'll have to assign your class as the delegate of the text fields.
Example:
class MyClass: UITextFieldDelegate {
func setup() { // meaningless method name
textField1.delegate = self
textField2.delegate = self
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
if (textField === textField1) {
textField2.becomeFirstResponder()
} else if (textField === textField2) {
textField2.resignFirstResponder()
} else {
// etc
}
return true
}
}
Follow the steps given below:
1) You will be needing to set the tags in the incremental sequence of the textfields in xib/Storyboard or in code.
2) Set the delegate for each of the textfields.
3) Then paste the following code in your view controller to have the desired effect:
func textFieldShouldReturn(textField: UITextField) -> Bool
{
let nextTag: Int = textField.tag + 1
let nextResponder: UIResponder? = textField.superview?.superview?.viewWithTag(nextTag)
if let nextR = nextResponder
{
// Found next responder, so set it.
nextR.becomeFirstResponder()
}
else
{
// Not found, so remove keyboard.
textField.resignFirstResponder()
}
return false
}
Hope this helps!!
If you have two textfield :
- textField1
- textField2
func textFieldShouldReturn(textField: UITextField!) -> Bool {
textField1.resignFirstResponder()
textField2.becomeFirstResponder()
return true
}
class ViewController: UIViewController,UITextFieldDelegate //set delegate to class
#IBOutlet var txtValue: UITextField //create a textfield variable
override func viewDidLoad() {
super.viewDidLoad()
txtValue.delegate = self //set delegate to textfile
}
func textFieldShouldReturn(textField: UITextField!) -> Bool { //delegate method
return true
}