I have a UIImage next to a text field. I want the image to change (to a check) if the text field passes a format test. So, if there are six characters entered, the image will change. I tried to use textFieldDidChange but I think this function only gets called once the field changes the first time. Is there a function I can use that gets called every time a character is entered? Is there a better way to do it?
Use an action on the editing changed event. This can be accomplished through an IBAction or by adding a target manually.
IBAction
Add this method in your view controller and connect the outlet to the editingChanged event in your xib or storyboard:
#IBAction func textFieldChanged(_ sender: UITextField) {
// Your code here
}
Add Target
override func viewDidLoad() {
super.viewDidLoad()
yourTextField.addTarget(self, action: #selector(textFieldChanged(_:)), for: .editingChanged)
}
func textFieldChanged(_ sender: UITextField) {
// Your code here
}
According to Apple's documentation. Under the Discussion section, it says,
The text field calls this method whenever user actions cause its text to change. Use this method to validate text as it is typed by the user.
"This method" refers to textField(_:shouldChangeCharactersIn:replacementString:)
This is the full method:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
<code>
}
Related
So I really am sorry if my post is a little off, this is my first time asking question.
I have a subclass of UITextView, let's call it A.
class A: UITextView{
var customDelegate: CustomTextViewDelegate!
}
extension A: UITextViewDelegate{
func textViewDidChange(_ textView: UITextView){
if let delegate = customDelegate{
delegate.textViewDidChange(textView)
}
}
func textViewShouldChangeTextIn(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if let delegate = customDelegate{
return delegate.textViewShouldChangeTextIn(baseTextView: textView, range: range, text: text)
}
return true
}
}
protocol CustomTextViewDelegate{
func textViewDidChange(_ customTextView: UITextView)
}
class SecondVC: UIViewController{}
extension SecondVC: CustomTextViewDelegate{
func textViewShouldChangeTextIn(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool
return false //this is where the problem is
}
As you can see, A delegate UITextViewDelegate to itself. I instantiate A to two different ViewController. in FirstVC, textViewDidChange method from the delegate is getting called normally, but on the secondVC it does not.
Now, here is the problem, any other method from UITextViewDelegate is getting called normally on SecondVC like textView(ShouldChangeTextIn), textViewDidEndEditing. Do anyone know what is going on? and where the problem could come from?
I have tried to make sure that not a single line of code try to assign the textViewDelegate to other class.
I have found the issue, I want to simplify things when I made this post by not mentioning quite few things. But, let's just say that I make CustomTextViewDelegate so that whatever VC instantiate the A (CustomTextView) can still implement their own custom "UITextViewDelegate". The problem lies when SecondVC TextView(shouldChangeText in) from CustomTextViewDelegate return false, therefore TextViewDidChange is not getting called.
Is there any way in which I can send information from a textfield to a label automatically while writing for example if I have 2 texfield and 1 label
one by name and the other by last name
that when writing a single letter or a name this automatically appears in the label
some way to do this with de button
-> #IBAction func bt(_ sender: Any) { text =texfield!.text text = txfield!.text text.text = "\(textt!) \(texxt!)"
You can add this text change listener in your viewDidLoad method of View Controller.
yourTextField.addTarget(self, action: #selector(ViewController.textFieldDidChange(_:)), for: .editingChanged)
And add this function to your View Controller
#objc func textFieldDidChange(_ textField: UITextField) {
yourLabel.text = textField.text
}
I realize this is a trivial question with tons of answer on SO. I may just need a pair of fresh eyes as I've triple checked everything and cannot see where I am going wrong with this. I just want to dismiss the keyboard on hitting the return key. I'm setting the delegate properly and implementing the proper methods, so why won't the keyboard dismiss?
Does having a collectionView in the viewController complicate things? (text field is NOT inside collectionView)
class SearchController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UITextFieldDelegate {
#IBOutlet weak var searchBar: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
searchBar.delegate = self
setupUI()
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
searchBar.resignFirstResponder()
return true
}
Things I've tried:
cleaning the project
restarting xcode
changing the searchBar.resignFirstResponder() to textField.resignFirstResponder()
setting the delegate for the text field inside IB instead of in viewDidLoad
What the heck am i missing here!?
You need to implement the proper text field delegate method. There is no such delegate method as textFieldShouldReturn(textField:). The proper method is textFieldShouldReturn(_:).
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
searchBar.resignFirstResponder()
return false
}
The _ makes a huge difference. You may have copied an old Swift 2 implementation.
It's best to let Xcode perform code completion to ensure you get the correct signature of any method you are implementing or calling.
Use this code
view.endEditing(true)
I have a textfield and textview in my custom tableviewcell.
I have 4 different prototype cell with 4 different class created. there is a textfield in 1 prototype cell and a textview in the other.
I am not sure how I can do it and I dont understand the obj-c answers out there.
I've tried
override func viewDidLoad() {
super.viewDidLoad()
let tap: UIGestureRecognizer = UIGestureRecognizer(target: self, action: #selector(UIInputViewController.dismissKeyboard))
view.addGestureRecognizer(tap) }
and
func dismissKeyboard() {
self.view.endEditing(true)
}
I wanted to try
UITextFieldDelegate and touchesbegan and textfieldshouldreturn method, but there are no textfields to call in my tableviewcontroller.
Go to attributes inspector in storyboard and click tableView and set keyboard to dismiss interactively.
Or
Set textField delegate and implement
override func viewDidLoad() {
super.viewDidLoad()
textField.delegate = self
}
func textFieldShouldReturn(textField: UITextField) -> Bool // called when 'return' key pressed. return false to ignore.
{
textField.resignFirstResponder()
return true
}
I had same problem, you can solve this with IQKeyboardManager, you don't need to complicate things with the custom cell classes, just install it on your project, when you're all set with installation, in the appDelegate inside the didFinishLaunchingWithOptions method, add this line of code:
IQKeyboardManager.shared.shouldResignOnTouchOutside = true
Get IQKeyboardManager from here.
I am having trouble dismissing the keyboard of a text view in swift.
I was able to dismiss a textfield with the following
#IBAction func DismissKeyboard(sender: AnyObject)
{
self.resignFirstResponder()
}
But I'm not sure how I go about it with a text view
You have to set the textview.delegate to self and use the shouldChangeTextInRange function to resign on pressing return.
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
if text == "\n" // Recognizes enter key in keyboard
{
textView.resignFirstResponder()
return false
}
return true
}
swift 3
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if text == "\n" {
textView.resignFirstResponder()
return false
}
return true
}
just add the UITextView as an IBOutlet and use the same function:
#IBAction func DismissKeyboard(sender: AnyObject) {
yourtextView.resignFirstResponder()
}
This is a much better more-intuitive (for your user) solution for dismissing soft keyboard. The problem with the "\n" solution is the user cannot insert line-breaks in the textView-- as hitting the return/done button on the keyboard will dismiss the keyboard before the line break occurs. The method below lets you keep that functionality while teaching the user that just tapping outside text-entry fields is a standard way of dismissing keyboards.
// MARK: - dismiss keyboard when user taps outside of text boxes
override func viewDidLoad() {
super.viewDidLoad()
configureTapGesture()
}
private func configureTapGesture() {
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(WriteJournalEntryViewController.handleTap))
view.addGestureRecognizer(tapGesture)
}
#objc func handleTap() {
view.endEditing(true)
}
(assumes this code is inside a UIViewController custom subclass named "WriteJournalEntryViewController).
view = your entire view in the UIViewController, so it works for more than just your textView object.
endEditing = a method for UIView class, you can read its documentation.