I am trying to have my inputs inside of my UITextField show up in the debugger console, when I am typing in the created TextField however the Delegate Methods don't seem to be responding. I am expecting to see my print statement that are seen below for my UIdelegate methods, like when I first started typing, while I type, and when I press the 'return key'. All delegate methods do not seem to be activated, and I am not sure how to make my Textfield link to the delegate method directly. In addition, I have another UITextField (Not shown here), would I have to 'addTarget' to differentiate between the two?
class ViewController: UIViewController, UITextFieldDelegate {
let createUserName: UITextField = {
var myTextField = UITextField ()
myTextField.translatesAutoresizingMaskIntoConstraints = false
myTextField.placeholder = "Username" //set placeholder text
myTextField.font = UIFont.systemFont(ofSize: 14) // set font size of text field
myTextField.layer.borderWidth = 1.0 //set width
myTextField.layer.borderColor = UIColor.red.cgColor//set background color to a ui color
myTextField.layer.backgroundColor = UIColor.white.cgColor
myTextField.layer.cornerRadius = myTextField.frame.height/2
myTextField.autocorrectionType = .no // disable autocorrect when typing for .no, enable with .yes
myTextField.isSecureTextEntry = false// masked text
myTextField.keyboardType = .default //keyboard style is set to default
myTextField.returnKeyType = .default //retuen key text changed to "Done" instead of return
myTextField.clearButtonMode = .whileEditing
myTextField.delegate = self as? UITextFieldDelegate
return myTextField
}()
override func viewDidLoad() {
super.viewDidLoad()
createUserName.delegate = self
view.addSubview(createUserName)
setupUserName()
}
//UITextField Delegate methods
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
print("textfield should begin editting")
return true
}
func textFieldDidBeginEditing(_ textField: UITextField) {
print("text field edit")
}
//see string that is typed in debugger for use to validate password and crossreference username
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if let textFieldString = textField.text, let swtRange = Range(range, in: textFieldString) {
let fullString = textFieldString.replacingCharacters(in: swtRange, with: string)
print("FullString: \(fullString)")
}
return true
}
//dismiss keyboard when return button is pressed
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
print("text field return")
return true
}
}
Your viewController should inherit from UITextFieldDelegate
class YourViewController : UIViewController, UITextFieldDelegate {
// your code
}
Also in your ViewDidLoad, move your createUsername.delegate = self to last line.
That string:
myTextField.delegate = self as? UITextFieldDelegate
tell us that your VC don't directly conform protocol UITextFieldDelegate...
If you conformed swift doesn't add as? cast ...
Related
I would like to have code for anytime a UItextfield is empty. Not just on the viewdidload but all the time. I tried putting something like if textField.isEmpty == true in the editing changed action although the issue I was having is if you type more than 5 characters and then hold down backspace the code doesn't get triggered. Any ideas for what to do?
Hi you need to subscribe on editing changedÂ
How to check if the field is empty?
let textField = UITextField()
textField.addTarget(self, action: #selector(textChanged), for: .editingChanged)
#objc func textChanged () {
if textField.text == "" || textField.text == nil {
print("IS EMPTY")
} else {
print("NON EMPTY")
}
}
How to set max length to UITextField
class ViewController: UIViewController, UITextFieldDelegate {
override func viewDidLoad() {
let textField = UITextField()
textField.delegate = self
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard let textFieldText = textField.text,
let rangeOfTextToReplace = Range(range, in: textFieldText) else {
return false
}
let substringToReplace = textFieldText[rangeOfTextToReplace]
let count = textFieldText.count - substringToReplace.count + string.count
return count <= 5
}
}
My swift code below goal is when the user enters something into textfield tt it reflects it in currentPageLabel. The func that I thought would do this is having no effect. Nothing I enter into the textfield displays on the label. All of my code does not use a storyboard.
var currentPageLabel = UILabel()
var tt = UITextfield()
func textFieldDidBeginEditing(_ textField: UITextField) {
currentPageLabel.text = tt.text
}
Try this UITextFieldDelegate method:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let text = (textField.text as NSString?)?.replacingCharacters(in: range, with: string)
currentPageLabel.text = text
return true
}
You can use addTarget feature in this case! Just add target to your textField in viewDidload method, and add selector method marked with #objc textFieldDidChange. Inside textFieldDidChange function set text to your label!
textfield.addTarget(self, action: #selector(textFieldDidChange), for: .editingChanged)
#objc func textFieldDidChange(_ textField: UITextField) {
currentPageLabel.text = textField.text
}
I have an addTarget set up on UITextField that clears the placeholder text when editingDidBegin. But I don't know how to restore the placeholder text if the user clicks on another UITextField, or the field is left empty.
This is located in viewDidLoad()
firstInitialTextField.addTarget(self, action: #selector(clearPlaceholderInTextField), for: UIControl.Event.editingDidBegin)
This function is located in the main body of the program.
#objc func clearPlaceholderInTextField() {
firstInitialTextField.placeholder = ""
}
I have several fields I would like to apply this same functionality to.
Create outlet collection for all the textfields like
#IBOutlet var textFs:[UITextField]!
with different tag for each , And array of placeHolders that you set in viewDidLoad
var placeholders = [String]()
Then set the vc as the delegate for all of them in viewDidLoad
textFs.forEach { $0.delegate = self }
Implement
func textFieldDidBeginEditing(_ textField: UITextField) {
textField.placeholder = ""
}
func textFieldDidEndEditing(_ textField: UITextField) {
textField.placeholder = placeholders[textField.tag]
}
I am using the CosmicMind library for Material design and I am trying to set up basic textfields with some error checking but the documentation is not very good.
I have set up my text fields like the following:
#IBOutlet weak var userNameField: ErrorTextField!
userNameField.placeholder = "Enter Username"
userNameField.delegate = self
userNameField.error = "Text is too long" // App Crashes here
userNameField.errorColor = Color.red.base
App crashes with EXC_BAD_ACCESS
I validate my field like this:
func textField(textField: TextField, didChange text: String?) {
if textField == userNameField {
if validateUsername(text: textField.text!) {
userNameField.isErrorRevealed = true
} else {
userNameField.isErrorRevealed = false
}
}
}
Even if I remove that line, app crashes on userNameField.isErrorRevealed = true too.
I have created following code with same library which are you using, which are working fine. I have create textField programatically.
import UIKit
import Material
class ViewController: UIViewController {
fileprivate var emailField: ErrorTextField!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = Color.grey.lighten5
emailField = ErrorTextField()
emailField.placeholder = "Email"
emailField.error = "Text is too long"
emailField.delegate = self
self.view.layout(emailField).height(40).width(200).centerVertically().centerHorizontally()
}
}
extension ViewController: TextFieldDelegate {
public func textFieldDidEndEditing(_ textField: UITextField) {
(textField as? ErrorTextField)?.isErrorRevealed = false
}
public func textFieldShouldClear(_ textField: UITextField) -> Bool {
(textField as? ErrorTextField)?.isErrorRevealed = false
return true
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
(textField as? ErrorTextField)?.isErrorRevealed = true
return true
}
}
See this sample project: Sample Project
I hope this will help you.
I am trying to simply capture the string typed into a UITextField in a GameController class that supports a MainViewController. My code below doesn't capture it into the wordAttempt string. Maybe its something to do with the textfield delegate which I am not sure how to set... Any help very much appreciated!
Class MainViewController: UIViewController {
required init?(coder aDecoder: NSCoder) {
controller = GameController()
super.init(coder: aDecoder)
}
override func viewDidLoad() {
super.viewDidLoad()
let gameView = UIView(frame: CGRectMake(0, 0, ScreenWidth, ScreenHeight))
self.view.addSubview(gameView)
controller.gameView = gameView
}
and then
class GameController: NSObject, UITextFieldDelegate {
var gameView: UIView!
var writeText: UITextField!
self.writeText = UITextField(frame: CGRectMake(100,100,200,50))
writeText.delegate = self
writeText.becomeFirstResponder()
gameView.addSubView(writeText)
textFieldShouldReturn(writeText)
textFieldDidEndEditing(writeText)
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
writeText.resignFirstResponder()
textFieldDidEndEditing(writeText)
return true
}
func textFieldDidEndEditing(textField: UITextField) {
self.wordAttempt = writeText.text ?? ""
writeText.resignFirstResponder()
}
If you want get informed anytime user enter some characters to your UITextField you should subscribe to it changes.
// inside your GameController
self.writeText = UITextField(frame: CGRectMake(100,100,200,50))
writeText.addTarget(self, action: "textFieldDidChange:", forControlEvents: UIControlEvents.EditingChanged)
writeText.becomeFirstResponder()
...
func textFieldDidChange(textField: UITextField) {
let inputText = textField.text ?? ""
}
And you will get text that user type in intpuText variable. Because of optional type you should unwrap it before use. And ?? "" means "if it nil put empty string to intputText, otherwise - text". This is why you see Optional("") when you output text.
If you need to know only when user stop typing consider textFieldDidEndEditing(_:) method of UITextFieldDelegate.
class GameController: NSObject, UITextFieldDeleage {
...
self.writeText = UITextField(frame: CGRectMake(100,100,200,50))
writeText.delegate = self
writeText.becomeFirstResponder()
...
func textFieldDidEndEditing(textField: UITextField) {
let inputText = textField.text ?? ""
}
You need to have it detect that the text has changed. You could do this say with a separate button press. Or you could use the textField delegate function textFieldDidEndEditing and textFieldDidBeginEditing to detect when the text has changed. Note that you would have to set the textfield's delegate.