in swift how to dismiss the key board - swift

I am wondering how to dismiss a key board if the user touches outside the UITextField. I am using Xcode 6.1. I added a UITextField to a UIViewController as per the below thru ViewDidLoad() function. Any help on dismissing the key board would be much appreciated.
class PickerdemoViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate, UITextFieldDelegate{
var textBox1 : UITextField!
override func viewDidLoad() {
//..................adding text box.........................//
self.textBox1 = UITextField (frame: CGRectMake(100, 152.5, 50, 35))
textBox1.delegate = self
textBox1.backgroundColor = UIColor.whiteColor()
textBox1.placeholder = "enter"
textBox1.keyboardType = UIKeyboardType.DecimalPad
self.textBox1.resignFirstResponder()
textBox1.keyboardAppearance = UIKeyboardAppearance.Default
self.view.addSubview(textBox1)
super.viewDidLoad()
}

You need to have a reference to the UITextField so make a property value like this
class MyClass: UIViewController {
var textBox1: UITextField!
...
// create your textfield where ever you were by assigning it to self.textBox1
}
Then to dismiss the keyboard you resign its as the first responder.
self.textBox1.resignFirstResponder()
Update to dimiss keyboard
Dismissing on return/done with the textField delegate method
func textFieldShouldReturn(textField: UITextField) -> Bool {
self.textBox1.resignFirstResponder()
return true
}
Dismissing on a button click (custom IBAction method)
#IBAction func buttonClicked(sender: UIButton!) {
self.textBox1.resignFirstResponder()
}

This will dismiss the keyboard by tapping screen. Make sure to not put it in the viewDidLoad.
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { // this func lets you close keyboard by touching screen
self.view.endEditing(true) // this line lets you close keyboard by touching screen
}

Related

Move view using Scroll View to prevent keyboard from obscuring text field or text view

I am implementing an app where tapping a button will pop up a location entry screen which is implemented with Modally presented Segue and Visual Effect with Blur to make the entry window appear hovering above the main screen.
The pop up screen has a text field for location name and a multi line text view for remarks.
Problem is the multi line text view is partially obscured by the keyboard on smaller devices and in landscape view.
Landscape View
Portrait View
Modal Segue View
I tried to utiize the solution described here, which is supposed to utilize scroll view to shift the view when keyboard appears, but it doesn't seem to work for my project: Move a view up only when the keyboard covers an input field
This question doesn't answer my problem as my text field and view are inside another view to make it appear like a popup to the main screen: Move a view up only when the keyboard covers an input field
In order to implement the pop up view (in a modal segue) I placed the text field and view inside a View which is placed inside a Scroll View which is located inside the view of the Visual Effects with Blur View.
Another problem I'm experiencing is I impleneted the following code to dismiss keyboard when tapping outside the text field/view, but for some reason it doesn't seem to work
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
{
self.view.endEditing(true)
}
Here is the code for the View Controller of the pop up view in Xcode 9.2
Archive of the project: Xcode Project Archive
//
// LocationEntryScrollViewController.swift
//
import UIKit
class LocationEntryScrollViewController: UIViewController, UITextViewDelegate, UITextFieldDelegate {
#IBOutlet weak var ScrollView: UIScrollView!
#IBOutlet weak var LocationEntryView: UIView!
#IBOutlet weak var LocationTextField: UITextField!
#IBOutlet weak var RemarksTextView: UITextView!
var activeTextField: UITextField?
var activeTextView: UITextView?
override func viewDidLoad()
{
super.viewDidLoad()
registerForKeyboardNotifications()
LocationEntryView.layer.cornerRadius = 10
LocationEntryView.layer.masksToBounds = true
LocationTextField.delegate = self // dismiss keyboard when tapped outside keyboard
RemarksTextView.delegate = self // dismiss keyboard when tapped outside keyboard
}
override func viewDidAppear(_ animated: Bool)
{
super.viewDidAppear(animated)
LocationTextField.becomeFirstResponder()
RemarksTextView.becomeFirstResponder()
}
/**
* Called when the user click on the view (outside the UITextField).
*/
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
{
self.view.endEditing(true)
}
override func viewDidDisappear(_ animated: Bool)
{
deregisterFromKeyboardNotifications()
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func DoneButtonTapped(_ sender: Any)
{
dismiss(animated: true, completion: nil)
}
#IBAction func CancelButtonTapped(_ sender: Any)
{
}
#objc func keyboardWasShown(notification: NSNotification)
{
//Need to calculate keyboard exact size due to Apple suggestions
self.ScrollView.isScrollEnabled = true
var info = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize!.height, 0.0)
self.ScrollView.contentInset = contentInsets
self.ScrollView.scrollIndicatorInsets = contentInsets
var aRect : CGRect = self.view.frame
aRect.size.height -= keyboardSize!.height
if let activeTextField = self.activeTextField
{
if (!aRect.contains(activeTextField.frame.origin))
{
self.ScrollView.scrollRectToVisible(activeTextField.frame, animated: true)
}
}
if let activeTextView = self.activeTextView
{
if (!aRect.contains(activeTextView.frame.origin))
{
self.ScrollView.scrollRectToVisible(activeTextView.frame, animated: true)
}
}
}
#objc func keyboardWillBeHidden(notification: NSNotification)
{
//Once keyboard disappears, restore original positions
let info : NSDictionary = notification.userInfo! as NSDictionary
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, -keyboardSize!.height, 0.0)
self.ScrollView.contentInset = contentInsets
self.ScrollView.scrollIndicatorInsets = contentInsets
self.view.endEditing(true)
self.ScrollView.isScrollEnabled = false
}
func textFieldDidBeginEditing(_ textField: UITextField)
{
activeTextField = textField
}
func textFieldDidEndEditing(_ textField: UITextField)
{
activeTextField = nil
}
func textViewDidBeginEditing(_ textView: UITextView)
{
activeTextView = textView
}
func textViewDidEndEditing(_ textView: UITextView) {
activeTextView = nil
}
func registerForKeyboardNotifications()
{
//Adding notifies on keyboard appearing
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
func deregisterFromKeyboardNotifications()
{
//Removing notifies on keyboard appearing
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
}

dismiss keyboard tapping background with action

My app has two UITextFields. Both I have dismissing by tapping the background because they are using the decimal keyboard. I want it so if say textField1 is up and you tap the background a specific button pops up with the actions for textField1 and vice versa. Currently if you tap the background with out any keyboard up it still pops up a button. Any help would be awesome thanks.
#IBOutlet weak var textField: UITextField!
#IBOutlet weak var button: UIButton!
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
button.isHidden = false
}
override func viewDidLoad() {
super.viewDidLoad()
self.textField.delegate = self
button.isHidden = true
}

Dismiss UITextField keyboard?

I have multiple textfields
#IBOutlet var emailLogin: UITextField!
#IBOutlet var passLogin: UITextField!
#IBOutlet var emailSignUp: UITextField!
#IBOutlet var passSignUp: UITextField!
as of now these aren't really needed, because of how I am dismissing it by tapping anywhere on the screen, however I also want it to dismiss when I press the return key.
override func viewDidLoad() {
super.viewDidLoad()
self.emailLogin.delegate = self
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(LoginViewController.dismissKeyboard))
view.addGestureRecognizer(tap)
}
First question: When I need to dismiss with only one I would set the delegate like so, but how do I handle this when I have multiple views that need to be dismissed on return key?
Also, there are two separate views, but both use the same class. Is this a problem for what I am trying to do?
From here
func dismissKeyboard() {
view.endEditing(true)
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
This dismisses the keyboard but only for the textfield that I set as self.
Any info is appreciated!
EDIT:
Change your code to the following and it should work:
#IBOutlet var emailLogin: UITextField?
#IBOutlet var passLogin: UITextField?
#IBOutlet var emailSignUp: UITextField?
#IBOutlet var passSignUp: UITextField?
emailLogin?.delegate = self
passLogin?.delegate = self
emailSignUp?.delegate = self
passSignUp?.delegate = self
The IBOutlets from other class were not initialized when your LoginViewController loads, thus end up with unwrapping nil objects, which is not allowed in Swift. (You should be able to see that in your console output in Xcode.) Use optional variables will prevent that from happening.
Use ViewControllerDelegate to handle tap outside of any textField and textView. It will dismiss keyboard when you tap on outside of textField. Put below code in your view controller:
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesBegan(touches, withEvent:event)
self.view.endEditing(true)
}
You don't need to add TapGesture now to handle this.

How to make keyboard dismiss when I press out of searchbar on Swift?

I try to make my searchbar on swift, but I have a problem to dismiss keyboard on screen when I pressed out of searchbar. When I try with textfield, it works perfectly fine with this code.
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
self.view.endEditing(true)
}
It work when i press out of my textfield and then the keyboard is gone. I want to make like that with my searchbar, because when I use searchbar and use the same way like textfield, it doesn't work at all. Any reference or code is very useful for me.
try this :
self.mySearchController.searchBar.endEditing(true)
replace mySearchController with your created controller name..
If you did not create it programmatically but instead you just dragged a search bar from library then IBoutlet your searchable to your class and reference it as:
self.mySearchBar.endEditing(true)
I found it easier and simplier to use Table View for dismissal. (If you're using table view)
Swift 4:
self.tableView.keyboardDismissMode = .onDrag
Tested and working!
func searchBarSearchButtonClicked(searchBar: UISearchBar)
{
searchActive = false;
self.mySearchBar.endEditing(true)
}
Edit for Swift 4.2
func searchBarSearchButtonClicked(_ searchBar: UISearchBar)
{
searchActive = false
self.searchBar.endEditing(true)
}
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
searchActive = false;
searchProject.resignFirstResponder()
}
This method will be invoked when user click search button on keyboard.So here we can dismiss keyboard.I think this is the right method.
Firstly, Apple's UISearchBarDelegate is the correct solution to hide keyboard when users click a search button while UISearchBar's instance is the first responder (learn UIResponder). In short, searchBarSearchButtonClicked(_:) is what you need for this task.
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
searchBar.resignFirstResponder() // hides the keyboard.
doThingsForSearching()
}
If it doesn't work, check, does your controller conform to UISearchBarDelegate and secondly, does UISearchBarDelegate know about your class implementation (if you don't quite understand what am I talking about, you should learn delegation pattern starting to read here):
class YourAwesomeViewController: UIViewController, UISearchBarDelegate { // pay attention here
#IBOutlet weak var yourSearchBar: UISearchBar!
override func viewDidLoad() {
super.viewDidLoad()
self.yourSearchBar.delegate = self // and it's important too
}
}
Further, if you need to hide the keyboard touching outside of search bar without touching the search button (the user may change his mind to search something), UITapGestureRecognizer is a simple way too to deal with that.
Ctrl-drag a Tap Gesture Recognizer from the Object Library to your View Controller.
Ctrl-drag the recently added Tap Gesture Recognizer from the document outline in the storyboard to your class implementation as IBAction.
Finally, write a code:
#IBAction func tapToHideKeyboard(_ sender: UITapGestureRecognizer) {
self.yourSearchBar.resignFirstResponder()
}
Also, don't forget to create #IBOutlet for the search bar to have an access inside your class implementation.
Both variants above work well in my project.
Swift 4+:
You can try, creating a tap gesture and add in the self.view
let singleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.singleTap(sender:)))
singleTapGestureRecognizer.numberOfTapsRequired = 1
singleTapGestureRecognizer.isEnabled = true
singleTapGestureRecognizer.cancelsTouchesInView = false
self.view.addGestureRecognizer(singleTapGestureRecognizer)
and in selector func you call self.searchBar.resignFirstResponder
#objc func singleTap(sender: UITapGestureRecognizer) {
self.searchBar.resignFirstResponder()
}
You can use a general UIViewController extension
Just add a new swift file on the project and paste the following code snippet
Code
extension UIViewController {
func hideKeyboardWhenTappedAround() {
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard(_:)))
tap.cancelsTouchesInView = false
view.addGestureRecognizer(tap)
}
#objc func dismissKeyboard(_ sender: UITapGestureRecognizer) {
view.endEditing(true)
if let nav = self.navigationController {
nav.view.endEditing(true)
}
}
}
Now call hideKeyboardWhenTappedAround() from viewDidLoad method where you want keyboard hiding feature.
class MaCaveViewController: UIViewController, UISearchBarDelegate {
#IBOutlet weak var searchBar: UISearchBar!
override func viewDidLoad() {
super.viewDidLoad()
searchBar.delegate = self
}
// When button "Search" pressed
func searchBarSearchButtonClicked(_ searchBar: UISearchBar){
print("end searching --> Close Keyboard")
self.searchBar.endEditing(true)
}
}
This works very well for me.
we can do this with following methods
func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
searchBar.showsCancelButton = true;
}
func searchBarTextDidEndEditing(searchBar: UISearchBar) {
searchBar.showsCancelButton = false;
}
This works for me in Swift 4
func searchBarSearchButtonClicked(_ searchBar: UISearchBar){
self.searchBar.endEditing(true)
}

Getting nil value on textview and button

Hello im am making an app where the user can press a button and a random link shows upp. I have in the textfile tried to name blblbl.delegate = self but when running the code it suddenly says that all of my textview and buttons has the value of nil.
class ViewController: UIViewController, UITextViewDelegate,
NSObjectProtocol {
#IBOutlet weak var firstbutton: UIButton!
#IBOutlet weak var firsttextview: UITextView!
let links = ["http://www.google.com","http://www.yahoo.com",
"http://www.discovery.com"]
var currentLinkIndex : Int = 0
override func viewDidLoad() {
Firsttextview.delegate = self
configureTextView()
super.viewDidLoad()
}
func configureTextView() {
func textView(firsttextview: UITextView!, shouldInteractWithURL
URL:
NSURL, inRange characterRange: NSRange) -> Bool {
let url = NSURL(string:links[currentLinkIndex])
UIApplication.sharedApplication().openURL(url!)
return false
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func firstaction(sender: UIButton) {
let random : Int = Int(arc4random()) % 3
Firsttextview.text = links[random]
currentLinkIndex = random
}
}
How do a solve this problem? Does i some how have to give the textview and button a value! Thanks in advance!
I guess you need to change :
Firsttextview.delegate to firsttextview.delegate and
Firsttextview.text = links[random] to firsttextview.text = links[random]
I tried to recreate your example by :
Creating a button in the storyboard
Creating the textview in the storyboard
Create + drag and drop to my ViewController Class the IBOutlet firstbutton from the button in the storyboard
Create + drag and drop to my ViewController Class the IBOutlet firsttextview from the textview in the storyboard
Create + drag and drop to my ViewController Class the IBAction firstaction from the button in the storyboard
If the button and the label are created in the storyboard, they don't need to be initialized in your code.
By doing this, your code worked for me.