How to dismiss keyboard for UITextView - swift

The following triggers when the Done button is clicked on the keyboard. It goes into the conditional and returns false. However, the keyboard remains on the screen.
class MyViewController: UIViewController, UITextViewDelegate{
func textView(textView: UITextView!, shouldChangeTextInRange: NSRange, replacementText: NSString!) -> Bool {
if(replacementText.isEqualToString("\n")) {
textBox.resignFirstResponder()
return false
}
return true
}
textBox is a delegate for the view. I have connected this through Interface Builder. Any ideas why it isn't dismissing the keyboard?

First of all please ensure that your My ViewController is a delegate of the textField,
And then, on the method shouldChangeTextInRange use the textView that is passed in the delegate method instead of your property textBox.
For example:
class MyViewController: UIViewController, UITextViewDelegate{
func viewDidLoad(){
super.viewDidLoad()
textBox.delegate = self
}
func textView(textView: UITextView!, shouldChangeTextInRange: NSRange, replacementText: NSString!) -> Bool {
if(replacementText.isEqualToString("\n")) {
textView.resignFirstResponder()
return false
}
return true
}

Related

Keyboard does not resign from view

I have a search bar in my app. The search bar is connected via a delegate to the main view controller. Even with textFieldShouldReturn and searchBarSearchButtonClicked nothing is happening.
I have tried to reconnect the delegate, and set the searchbar.delegate as self in my code (Results in a crash)
func searchBarSearchButtonClicked( _ searchBar: UISearchBar!){
print("Testing")
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
view.endEditing(true)
return true
}
You need to add UISearchBarDelegate in your class ViewController.

UITextFieldDelegate extension function does not triggers, why?

I have SequencedTextFields protocol, which contains sequence of text fields. When user taps Return button on keyboard, current text field should resign first responder and next text field in the sequence should become first responder. And it works good, when I'm using direct implementation of UITextFieldDelegate protocol for view controller:
extension MyViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
nextInSequence(after: textField)?.becomeFirstResponder()
return true
}
}
But, when I'm trying to use default implementation, it does not triggers ever:
extension UITextFieldDelegate where Self: SequencedTextFields {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
nextInSequence(after: textField)?.becomeFirstResponder()
return true
}
}
What could be the reason? Or I've missed something?
UPDATE:
My view controller defining:
final class MyViewController: UIViewController, UITextFieldDelegate, SequencedTextFields
Setting up the delegate for the text fields:
The reason why your implementation is not working is because you are trying to extend an interface (UITextFieldDelegate) instead of a class, that's why it works when you use UIViewController instead.
What you can do is to create a custom class SequencedTextField that extends UITextField. Add a custom delegate (that I called sequencedDelegate that represents the class that implements your SequencedTextFields protocol.
Extend SequencedTextField to implement UITextFieldDelegate with your default implementation.
On MyViewController, set up your SequencedTextField delegate with the viewController itself.
At the end it should look something like this:
protocol SequencedTextFields: class {
func nextInSequence(after: UITextField) -> UITextField?
}
class SequencedTextField: UITextField {
weak var sequencedDelegate: SequencedTextFields?
}
extension SequencedTextField: UITextFieldDelegate {
public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
sequencedDelegate?.nextInSequence(after: textField)?.becomeFirstResponder()
return true
}
}
class MyViewController : UIViewController, SequencedTextFields {
var textField = SequencedTextField()
override func viewDidLoad() {
super.viewDidLoad()
textField.delegate = textField
textField.sequencedDelegate = self
}
func nextInSequence(after: UITextField) -> UITextField? {
// your view controllers nextInSequence implementation here
}
}
What is wrong with your code?
The first extension is the extension of your view controller MyViewController, that's why it is working. But the second one is the extension of UITextFieldDelegate. Those are completely two different things.
Not clear what you want to achieve.
This is how you can use your custom protocol
If you want to make one CustomProtocol for your special UITextField you can do like this.
CustomTextFieldProtocol
Declear the protocol
protocol SequencedTextFields: UITextFieldDelegate {
func checkSomeThing(_ textField: UITextField) -> Bool
}
Set the delegate
self.textField.delegate = self
ViewController Extension to implement your Delegate methods
extension ViewController: SequencedTextFields {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
nextInSequence(after: textField)?.becomeFirstResponder()
return true
}
func checkSomeThing(_ textField: UITextField) -> Bool {
print("Check here")
return true
}
}

return key pressed inside uitableviewcell swift

I have a textfield in each cell of my tableview. I want to quit keyboard when users pressed on the return key. I tried:
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
But it doesn't work and I can't seem to find a away to reference the textfield inside the cell of my tableview. Please help, thanks!
I assume that you have created IBOutlets of your textfield in your cell class.
Give your textfield delegate to self in cellForRow datasource method of UITableView
cell.yourTextField.delegate = self
You can give delegate form storyboard.
You should let your custom UITableViewCell class to confirms to UITextFieldDelegate:
class TableViewCell: UITableViewCell, UITextFieldDelegate {
// ...
}
In awakeFromNib you should your textfields delegate to the cell class:
override func awakeFromNib() {
// ...
textField.delegate = self
// ...
}
Finally, implement textFieldShouldReturn:
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
Hope that helped.

How to add text to an active UITextField

I have a couple of UITextField's and one UIButton. If I tap on the UIButton, I want to place some static text in the active UITextField.
So something like:
#IBAction func buttonEen(sender: UIButton) {
'active textField'.text = "static text"
}
But how do I determine which UITextField is the active UITextField and how do I reach it?
To write text in last active UITextField you have to make your UIViewController a delegate of UITextField
ex:
class ViewController: UIViewController, UITextFieldDelegate
declare a activeField variable
ex:
var activeField: UITextField?
then implements textFieldDidBeginEditing
ex:
func textFieldDidBeginEditing(textField: UITextField)
{
activeField = textField
}
So your button function will be something like
#IBAction func buttonEen(sender: UIButton) {
if activeField
{
activeField.text = "static text"
}
}
First you need to create your textfield delegate (probably in 'ViewDidLoad()') :
activeTxtField.delegate = self
Then you need to implement the textField delegate function:
extension 'YourVC': UITextFieldDelegate {
func textFieldDidBeginEditing(_ textField: UITextField) {
if textField == activeTxtField {
// Do whatever you want
// e.g set textField text to "static text"
}
}
}

Swift Dismiss UITextView Keyboard

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.