I have a UITextField object and take input from the textfield. If length of the input is shorter than 2, I want to give warning sign in the textfield bar.
Is this impossible ?
If it is so, how can I handle that ?
EDIT:
I just handled it. I put a label in the textfield and run auto layout. Then, I chose delegate of textfield and make InputViewController conform to UITextFieldDelegate protocol. Finally, I use func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
Implement UITextFieldDelegate in your view controller and use textFieldDidEndEditing to check text length.
func textFieldDidEndEditing(_ textField: UITextField) {
if let textFieldText = textField.text {
print("textFieldText length - \(textFieldText.count)")
if (textFieldText.count < 2) {
showWarning(message: "Your message here")
}
}
}
func showWarning(message: String?){
// show warning message using UIAlertController here.
}
You can use a custom class inherited from UIView and pack UITextField(No border style) and Iconic Font UILabel inside it.
Related
I have a ViewController which inherits from UITextFieldDelegate and serves as the delegate for the text field in the view. I would like to trigger an action whenever the text is edited.
I tried implementing the textField method, which is listed in the UITextFieldDelegate documentation:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
The documentation describes this textField method as triggered when the text should be changed, which occurs before the specified text is changed. Here is the line from the documentation:
Asks the delegate if the specified text should be changed.
As this textField method triggers before the text is changed rather than after, the text available at textField.text therefore contains the prior text, not the new text updated after the change. To access the new text, I would need to apply the range and replacementString parameters to textField.text to imitate how the text will be changed.
Is there an alternative to the textField method that is triggered not when the text will be changed, but instead when the text has been changed? I'm thinking that directly using the text after the change would prevent me from having to hack an imitation of the change beforehand.
Add a target with a selector for valueChanged and you'll be able to get the events like you need here.
// adding target
textField.addTarget(self, action: #selector(textChanged), for: .valueChanged)
// selector
#objc func textChanged(_ textField: UITextField) {
print(textField.text)
}
Have you tried textDidChangeNotification? you will have to add observer for keyboarddidshow(notification).
For ur Ref:
https://stackoverflow.com/a/52325593
Just write extension UITextfieldDelegate to viewController, you will have these pre-defined functions:
func textFieldDidBeginEditing(_ textField: UITextField) {
}
func textFieldDidEndEditing(_ textField: UITextField) {
}
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
}
I am using RxSwift for a project. I am using the control events to handle the textfield events such as follows.
textField.rx.controlEvent([.editingDidEndOnExit]).subscribe { _ in }.disposed(by: disposeBag)
Now I need to handle a delegate method
textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
If I add the delegate to the textField, the controlEvents stop working.
Does anybody have a suggestion about how can I handle this case where I can use both the control events and delegate methods?
Or should I just remove either of these handling.
Thanks.
The editingDidEndOnExit control event stops working because the delegate is changing the behavior of the return key. Add a textFieldShouldReturn(_:) to your delegate and have it return true, then the controlEvent will work as expected.
extension ExampleViewController: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
// can only enter numbers with this. An example of the sort of thing you
// might want to put in this method.
return string.isEmpty || string.allSatisfy { !$0.unicodeScalars.contains { !NSCharacterSet.decimalDigits.contains($0) } }
}
// this method must exist. If you don't add a delegate to your text field,
// the default behavior is as if this returned true. If you add a delegate,
// then the field's default behavior changes to false and you have to
// implement this method to get it to return true again.
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
return true
}
}
I'm trying to change the colour of text being typed to white in UITextfield. I've used following code, which works but it doesn't change the colour of first letter to white. See the attached screenshot.
How to make it work so that colour of first letter also changes to white?
I've searched a lot but couldn't find the solution.
Tx in advance!
#IBAction func emailFieldEditingChanged(_ sender: UITextField) {
emailTextField.typingAttributes![NSAttributedStringKey.foregroundColor.rawValue] = UIColor.white
}
You'll want to set the delegate as Rakesha mentioned, but you have to change it each time the user inputs a character. Use this delegate method.
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
emailTextField.typingAttributes![NSAttributedStringKey.foregroundColor.rawValue] = UIColor.white
return true
}
//Set this in viewDidLoad, and don't forget to include the delegate.
emailTextField.delegate = self
My iOS app has username & password text fields. The username has specific limitations which are ensured by textField:shouldChangeCharactersInRange:replacementString: which returns NO for invalid resulting strings.
In iOS 11 I observe an issue when 'Password AutoFill' feature is used. In this case delegate method is called, but its result is ignored and text is replaced in any case regardless of returned value.
Is it by design, or bug, or maybe I'm missing something?
Yes it is by design, when you set the text property of an textfield, the delegate method below is not called, that's what it might happen
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
Neither this method below does help anyhow
func textFieldDidEndEditing(_ textField: UITextField) -> Bool {
return true
}
But you could subclass UITextfield, override text property create an extension for the UITextFieldDelegate with a default method 'textChanged' and implement the 'textChanged' method in the delegate
extension UITextFieldDelegate{
func textChanged(_ textField:UITextField){
print("textChanged")
}
}
class CustomTF: UITextField {
override var text: String?{
didSet{
print("didSet text")
delegate?.textChanged(self)
}
}
}
I have two problems.I am a beginner of swift
First,I want to hide the send button until user input frist character.I use textfield delegate functions that they don't implement this idea.
And then, I want to creat a blank line when user input in textfield.I know to use "textFieldShouldReturn" function ,but I use "\n" that it doesn't work for me.How to do this?
this is my code:
func textFieldDidBeginEditing(_ textField: UITextField) {
if textField.text?.isEmpty == false {
aButton.isHidden = true
sendButton.isHidden = false
}
}
update code:
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
self.textField.text = "\n"
return true
}
I also want the textfield change it height.let user can input their message. Does it can be implement?
Or I need to change textfield to textview.
You can use textfields delegate method to check when user start writing something in your textfield.
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
{
if textField == txtUserName //compare with your textfield object which you have taken by outlet
{
if string.characters.count >= 1 {
//make your button enable
}else
{
// disable your button
}
}
return true
}