I have a textfield, when something is typed in the textfield and "return" on the keyboard is pressed, the keyboard should hide. But it doesn't..
Here is the code I am using:
import UIKit
class EditTableViewController: UITableViewController, UITextFieldDelegate {
var product: Product?
#IBOutlet weak var productImageView: UIImageView!
#IBOutlet weak var ProductDescriptionTextView: UITextView!
#IBOutlet weak var productTitleLabel: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
println("loaded")
productImageView.image = product?.image
productTitleLabel.text = product?.title
ProductDescriptionTextView.text = product?.description
}
override func viewWillDisappear(animated: Bool) {
product?.title = productTitleLabel.text
product?.description = ProductDescriptionTextView.text
product?.image = productImageView.image!
}
func textFieldShouldReturn(textField: UITextField) -> Bool // called when 'return' key pressed. return NO to ignore.
{
println("return")
return true
}
}
In the console I get "loaded", but when I press return in the textfield, I don't get "return"
how come?
You forgot to set the UITextField's delegate to your view controller (self)
productTitleLabel.delegate = self - also note that you should name your variables properly to avoid confusion (productTitleTextField instead of a 'Label' suffix)
Or, instead of doing it programmatically, you can do it in storyboard by Ctrl-dragging from your textView to the view controller in storyboard, and select delegate on the popup.
Then, let your view controller conform to UITextFieldDelegate protocol:
class EditTableViewController: UITableViewController, UITextFieldDelegate {
....
func textFieldShouldReturn(textField: UITextField) -> Bool {
if textField == productTitleLabel {
textField.resignFirstResponder()
}
return true
}
}
In your viewDidLoad method you have to add:
productTitleLabel.delegate = self
And update your textFieldShouldReturn like this:
func textFieldShouldReturn(textField: UITextField) -> Bool // called when 'return' key pressed. return NO to ignore.
{
productTitleLabel.resignFirstResponder()
return true
}
And It will hide your keyboard when return key pressed.
Related
Environment: Xcode Version 8.2 (8C38)/Swift 3.0
A textFiled object in the View is wire up to a method named textFieldReturn in the controller via IBAction. The related codes are presented as follow
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func textFieldReturn(_ sender: Any) {
_ = (sender as AnyObject).resignFirstResponder()
}
}
What I expect:
When I hit the Return key of the virtual keyboard the function textFieldReturn(_:) will be called and the keyboard will be hidden
Issue Observer:
The function is not called after I tapped the return key, the keyboard is still there
Resource:
This code spinet come from the example of the Chapter 16 of the book iOS 10 App Development Essentials by Neil Symth (pp-114)
The only difference between this code and original code is the type of the function argument (Sender). It is AnyObject in the original book while I've got Any by default, therefore I've cast to AnyObject inside the function body
Question:
Its seems to be a decent book, but the sample code doesn't work for me. How can I call the resignFirstResponder() method when I hit the return key
Alternative try out:
Instead of using IBAction, I turn to the idea of delegate, I've set the VeiwController as the delegate of the textField
class ViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var tempText: UITextField! //reference the TextField as the variable **tempText** in the controller
override func viewDidLoad() {
super.viewDidLoad()
self.tempText.delegate = self //set up the delegation
}
func textFieldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return(true)
}
}
Problem
The alternative solution still not working.
Thanks for your time and help
Why are you not using the original delegate function of UITextField?
I think the default function will work as you want:
class ViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var tempText: UITextField! //reference the TextField as the variable **tempText** in the controller
override func viewDidLoad() {
super.viewDidLoad()
self.tempText.delegate = self //set up the delegation
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool{
textField.resignFirstResponder()
return false
}
}
Replace your textFieldReturn method with this and it should work just fine.
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
Make sure to keep the following in your viewDidLoad()
self.tempText.delegate = self
How do I find out if the keyboard is of type numeric, Twitter, email, etc...?
edit: Is there a way to detect keyboard type without using an outlet?
Consider that you have tow textFields in the ViewController, You will need to implement textFieldShouldBeginEditing method from UITextFieldDelegate protocol, as follows:
class ViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var tfEmail: UITextField!
#IBOutlet weak var tfPassword: UITextField!
func textFieldDidBeginEditing(_ textField: UITextField) {
if textField.keyboardType == .emailAddress {
// this is the tfEmail!
}
if textField.isSecureTextEntry {
// this is tfPassword!
}
}
}
Make sure their delegates are connected to the ViewController, programmatically:
tfEmail.delegate = self
tfPassword.delegate = self
or from the Interface Builder.
Note that you can recognize the keyboard type for the current textField by checking its keyboardType property, which is an instance of UIKeyboardType enum:
The type of keyboard to display for a given text-based view. Used with
the keyboardType property.
What about UITextView?
The same exact functionality should be applied when working with UITextViews, but you need to implement textViewDidBeginEditing(_:) method from UITextViewDelegate protocol instead of implementing textFieldShouldBeginEditing. Again, make sure the delegate of the textView is connected to the ViewController.
Also,
If your main purpose of checking the keyboard type is just for recognizing what is the current responded textField/textView, I suggest to do a direct check:
class ViewController: UIViewController, UITextFieldDelegate, UITextViewDelegate {
#IBOutlet weak var tfEmail: UITextField!
#IBOutlet weak var tfPassword: UITextField!
#IBOutlet weak var textViewDescription: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
tfEmail.delegate = self
tfPassword.delegate = self
textViewDescription.delegate = self
}
func textFieldDidBeginEditing(_ textField: UITextField) {
if textField === tfEmail {
// this is the tfEmail!
}
if textField === tfPassword {
// this is tfPassword!
}
}
func textViewDidBeginEditing(_ textView: UITextView) {
if textView === textViewDescription {
// this is description textview
}
}
}
For more information about === operator you might want to check this question/answers.
Hope this helped.
In addition to Ahmad F 's great answer, this is my approach of getting the current keyboard type, at any time:
Step 1: Delegate UITextField
class File: UIViewController, UITextFieldDelegate{//...}
Update viewDidLoad() to this:
#IBOutlet weak var normalTextField: UITextField!
#IBOutlet weak var numberTextField: UITextField!
#IBOutlet weak var emailTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
numberTextField.keyboardType = .numberPad
normalTextField.keyboardType = .default
emailTextField.keyboardType = .emailAddress
numberTextField.delegate = self
normalTextField.delegate = self
emailTextField.delegate = self
}
Step 2: Working with UITextField's methods:
Add a variable called keyboardType, as below:
var keyboardType: UIKeyboardType? = nil
Then, change it whenever a new textField begins editing:
func textFieldDidBeginEditing(_ textField: UITextField) {
keyboardType = textField.keyboardType
}
func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
keyboardType = nil
return true
}
Step 3: Create and call a function like below:
func getCurrentKeyboard() -> String{
if keyboardType == nil{
return "no current keyboard"
}
else if keyboardType == .numberPad{
return "number"
}
else if keyboardType == .emailAddress{
return "email"
}
else{
return "default"
}
}
#IBAction func displayCurrentKeyboard(_ sender: UIButton) {
print(self.getCurrentKeyboard())
}
And this outputs: email / number / no current keyboard / default, depending on the case.
If you want to check which type of keyboard it is with if-else statements, you can change your displayCurrentKeyboard() method to this:
#IBAction func displayCurrentKeyboard(_ sender: UIButton) {
let keyboardString = self.getCurrentKeyboard()
if keyboardString == "number"{
//...
}
else if keyboardString == "email"{
//...
}
else{
//...
}
}
And that's it! You can call this wherever you want in your code with this usage:
let keyboardString = self.getCurrentKeyboard()
NOTE: This method also handles the case of no keyboard visible on the screen, returning no current keyboard, in this case.
Let me know if this helps!
I took text field outlet collection and bind six text field over there.
I want to becomeFirstResponder of next text field which is in text field outlet collection.
I gave textfields tag 0 to 5 from storyboard.
see,
Main ViewController:
class ViewController: UIViewController {
#IBOutlet var txtSignUp: [UITextField]!
var arrayPlaceHolder:NSArray!
override func viewDidLoad() {
super.viewDidLoad()
arrayPlaceHolder = NSArray(array: ["1","2","3","4","5","6"])
self.setTextFieldValue()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
private func setTextFieldValue(){
for txtField in txtSignUp{
let tagTxt = txtField.tag
txtField.attributedPlaceholder = NSAttributedString(string:arrayPlaceHolder[tagTxt] as! String, attributes:[NSForegroundColorAttributeName:UIColor.black])
if(tagTxt != ((arrayPlaceHolder.count) - 1)){
txtField.returnKeyType = .next
}
txtField.delegate = self
}
}
}
extension ViewController:UITextFieldDelegate{
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
for txt in txtSignUp{
let nextTxt = (textField.tag + 1)
if txt.tag == nextTxt {
txt.becomeFirstResponder()
break
}
}
return true
}
}
Error:
whose view is not in the window hierarchy!
Explanation:
In this code, I am not able to become next text field as becomeFirstResponder.
Can anyone help me to resolve this issue.
On TVos you have to use the textFieldDidEndEditing function because textFieldShouldReturn won't work to set the next responder:
class MyViewController: UIViewController{
#IBOutlet weak var firstTextField: UITextField!
#IBOutlet weak var secondTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
firstTextField.delegate = self
secondTextField.delegate = self
firstTextField.tag = 0
secondTextField.tag = 1
}
}
extension MyViewController: UITextFieldDelegate {
func textFieldDidEndEditing(_ textField: UITextField) {
if (textField.tag == 0){
secondTextField.becomeFirstResponder()
}
}
}
I have the following code:
class ViewController: UIViewController, UITextFieldDelegate {
// MARK: Properties
#IBOutlet weak var layersTextField: UITextField!
#IBOutlet weak var innerShapeTextField: UITextField!
#IBOutlet weak var outerShapeTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
layersTextField.delegate = self
innerShapeTextField.delegate = self
outerShapeTextField.delegate = self
}
// MARK: UITextFieldDelegate
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
func textFieldDidEndEditing(textField: UITextField) {
// do something
}
}
Now in textFieldDidEndEditing(_:) I would like to do something, dependent on which UITextField called this method.
Is there any way to distinguish, which UITextField did this? Is there some kind of ID or identifier I can set on the UITextFields?
You can make this determination using one of two approaches: outlets or tags. For the outlet approach, declare an outlet instance variable (using the IBOutlet keyword) and then make an outlet connection. In your delegation method, test whether the passed-in text object is the same object referenced by the outlet, using pointer comparison.
For example, say you declare and connect an outlet named SSN. Your code might look something like Listing 3-1:
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
if (textField == SSN) {
// ...
return NO;
}
return YES;
}
// Translated to Swift:
func textFieldShouldEndEditing(textField: UITextField) -> Bool {
if textField === SSN {
// ...
return false
}
return true
}
You can check by the name of the next filed. if textField == layersTextField { //do what you want } and you can do that for any text field you need a specific action for.
You can create an IBAction instead:
In XCode 6.3.2, I have a UITextField:
#IBOutlet weak var uiswitchControlledTextField: UITextField!
I am now using a UISwitch (named mySwitch) to control its enabled or disabled state in the following way:
#IBOutlet weak var mySwitch: UISwitch!
mySwitch.addTarget(self, action: Selector("stateChanged:"), forControlEvents: UIControlEvents.ValueChanged)
//callback below:
func stateChanged(switchState: UISwitch) {
uiswitchControlledTextField.enabled = switchState.on
}
The above works well, however, I am looking to try if it would be possible to create a UITextFieldDelegate to control the above UITextField in the same way. So far, I have the following by implementing textFieldShouldBeginEditing, in which I wish to return false to disable the UITextField, but I don't know how to let the UISwitch dynamically return true or false from textFieldShouldBeginEditing
import Foundation
import UIKit
class SwitchControlledTextFieldDelegate: NSObject, UITextFieldDelegate {
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
return false; //do not show keyboard or cursor
}
}
In ViewController, I try to set
self.uiswitchControlledTextField.delegate = SwitchControlledTextFieldDelegate()
but it does not work as I wished. Any help would be appreciated.
self.uiswitchControlledTextField.delegate = SwitchControlledTextFieldDelegate()
The problem is that that line merely creates an instance of your SwitchControlledTextFieldDelegate class, which then immediately goes right back out of existence.
You need to use, as your text field delegate, some instance which already exists and which will persist - like, perhaps, your view controller!
(Xcode 7)
Use this:
override func viewDidLoad() {
super.viewDidLoad()
// Setting the delegate
self.textField3.delegate = self
self.editingSwitch.setOn(false, animated: false)
}
// Text Field Delegate Methods
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
return self.editingSwitch.on
}
#IBAction func toggleTheTextEditor(sender: AnyObject) {
if !(sender as! UISwitch).on {
self.textField3.resignFirstResponder()
}
}