How to remove the dismiss keyboard action on tapping outside MDCTextField - ios

I am trying to use an MDCTextField and a table view together. The MDCTextField filters the table view, then the user should tap a cell and the keyboard should dismiss and the table view should be hidden. The issue is that the keyboard dismisses and the table view is hidden before the table view registers that a cell was tapped. How can I register that a cell was tapped before the MDCTextField registers the tap?

I use this extension you can place in a helpers.swift file but this way you can use on any UIViewController
extension UIViewController {
func hideKeyboardWhenTappedAround() {
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard))
tap.cancelsTouchesInView = false
view.addGestureRecognizer(tap)
}
#objc func dismissKeyboard() {
view.endEditing(true)
}
}
To use it, on viewDidLoad() just add this self.hideKeyboardWhenTappedAround()
EDIT Based on comment
In theory the following code should help, but I haven't got around to test it, I've read that people couldn't get the touchBegan function to trigger but I also don't know any other way to do what you want.
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
let position = touch.location(in: view)
if let ip = tableView.indexPathForRow(at: position) {
let cell = tableView.cellForRow(at: ip)
print(cell.text)
}
}
}
The theory is the following
First we get the position where the tap occurred then we get the IndexPath for the row witch was taped (if exists) as we have the IndexPath we just get the cell.
In the example I gave you I print the cell text, but you can do any other operation that you want
I hope this is what you want and you can get it to work as I did not got around to test it and seems that some people are getting problems triggering the touchesBegan function

Related

How to dismiss keyboard by tapping on screen

I am looking for a simple solution in swift to add the ability to tap anywhere on screen and dismiss the keyboard. I read a lot of answers on here but they all throw errors for me. The one I have used before is this:
override func viewDidLoad() {
super.viewDidLoad()
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target:self, action: #selector(ViewController.dismissKeyboard))
view.addGestureRecognizer(tap)
This worked with one of my projects but it doesn't seem to work with any others. Whenever I try to add this to other projects I get error Type 'ViewController' has no member 'dismissKeyboard'.
You need to add a method above any reference to it. I put this code at the beginning of my files:
func dismissKeyboard() {
//Causes the view (or one of its embedded text fields) to resign the first responder status and drop into background
view.endEditing(true)
}
And then whenever I need to reference the .dismissKeyboard I use this inside the viewDidLoad():
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(LoginViewController.dismissKeyboard))
view.addGestureRecognizer(tap) // Allows dismissal of keyboard on tap anywhere on screen besides the keyboard itself
And make sure to replace 'LoginViewController' with the current View Controller. As per your example, that is just 'ViewController'
If you are looking for a more in depth answer, see this by 7KV7:
https://stackoverflow.com/a/5711504/6312593
You can try this one, its very simple solution, frequently used in swift to dismiss the keyboard.
Just add this function, that's it.
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
{
self.view.endEditing(true)
}
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: Selector("dismiss:"))
view.addGestureRecognizer(tap)
func dismiss(gest : UITapGestureRecognizer){
view.endEditing(true)
}
This is working fine, try it.

Event on tapping out of a UITextView (i.e. UITextView losing focus)

I'd like to perform some processing on my UITextView once the user has finished editing it and tapped somewhere else on the screen. What's the best practice?
I almost managed to get the desired effect with func textViewDidEndEditing(textView: UITextView) however this only runs when the user has tapped 'Enter' key on the keyboard (which people very rarely do - they just commit the changes by tapping on somewhere else on the screen.)
The problem with func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) is that it doesn't care whether the UITextView was edited or not.
I think you can add an UITapGestureRecognizer on the view which hold the textView. In the UITapGestureRecognizer's selector, you can add the logic codes to handle the process. You can check the length of the textView's text to determine the UITextView was edited or not. Here is some sample code:
override func viewDidLoad() {
super.viewDidLoad()
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap))
view.addGestureRecognizer(tapGestureRecognizer)
}
func handleTap() {
let text = textView.text
textView.resignFirstResponder() // loosing focus
if text.characters.count > 0 {
// textView edited
} else {
// textView not edited
}
}

Other actions occurring when sprite is tapped; how to prevent

I'm building a game that is primarily played by tapping the screen (anywhere). I have currently added a settings button that when tapped, opens up a settings window.
Problem is, when the settings button is tapped, interaction happens in the game too. Is there any way to prevent this from happening?
My settings screen works in conjunction with a settings function and the override touches began function through a boolean expression.
The game is played through a UITapGestureRecognizer that was added to the view in didMoveToView.
/* Game Interaction & Playability */
override func didMoveToView(view: SKView) {
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: Selector("tapped:"))
view.addGestureRecognizer(tap)
}
/* Settings Button Interaction */
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
let positionInScene = touch.locationInNode(self)
let touchedNode = self.nodeAtPoint(positionInScene)
if let name = touchedNode.name {
if name == "Settings" {
if settingsOpen == false {
settings()
} else {
settings()
}
}
}
}
}
Well, you've got a couple gesture recognizers working here. You don't actually need to add a recognizer to the view to know if someone is tapping it. That's handled already for you (hence the reason why touchesBegan works without adding another recognizer).
I would say remove that extra recognizer, and move the code for tapped: to your touchesBegan.

Handle Touch in UiCollectionView?

I have this big UICollectionView occupying major part of screen and there is a UIButton that shows a menu. I want to hide the menu when the user taps on any side of the screen which becomes unfortunately any part of UICollectionView for me. Tried on other view the below code, it works well...but not for UICollectionView. The function does not gets called.
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
hidemenu()
self.view.endEditing(true)
}
What is the problem? Thanks for your time.
OR
How to trigger touchesBegan in the UIViewController where UICollectionView resides
Here is the project.
While tapping on scrolling controllers (like UIScrollView, UITableView, UICollection etc) does not call touchesBegan method. because they have their own selector method. To handle such situation, you need to create UITapGesture on UICollectionView. While tapping on UICollectionView, its selector method called and do what ever you want.
Here are the link that guide you. how to create double Tap Gesture on UICollectionView. with help of this you can created single Tap gesture as well.
Collection View + Double Tap Gesture
Edit :
Do the following changes, it work fine.
Step 1 : Declare handleTap in SwipeMenuViewController.
func handleTap(sender: UITapGestureRecognizer) {
println("called swipe")
}
Step 2 : Create global variable of SwipeMenuViewController controller. that is out side of viewDidLoad()
var vc2 = SwipeMenuViewController()
Step 3 : Declare TapGesture in viewDidLoad()
var tap = UITapGestureRecognizer(target: vc2, action : "handleTap:")
tap.numberOfTapsRequired = 1
self.collectionView.addGestureRecognizer(tap)
Output :
called swipe
Hope this help you.
You can add a UITapGestureRecognizer to the UICollectionView and create an action to dismiss the view if the user touch outside your collection or anywhere.
Step 1 Create a tap gesture for dismiss the view
override func viewDidLoad() {
super.viewDidLoad()
...
let tap = UITapGestureRecognizer(target: self, action: #selector(didTapOutsideCollectionView(recognizer:)))
tap.numberOfTapsRequired = 1
self.collectionView.addGestureRecognizer(tap)
}
Step 2 With the tap location implement your desired action
#objc func didTapOutsideCollectionView(recognizer: UITapGestureRecognizer){
let tapLocation = recognizer.location(in: self.view)
//The point is outside of collection cell
if collectionView.indexPathForItem(at: tapLocation) == nil {
dismiss(animated: true, completion: nil)
}
}
You can directly use this method , whenever user taps on any part of collection view , your menu will be automatically hidden:-
func collectionView(_ collectionView: UICollectionView,
didSelectItemAtIndexPath indexPath: NSIndexPath)
{
hidemenu()
self.view.endEditing(true)
}
To detect tap on spaces between the cell, here is the code
self.collectionView.backgroundView = [[UIView alloc] initWithFrame:self.collectionView.frame];
self.collectionView.backgroundView.userInteractionEnabled = YES;
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(onTap:)];
self.collectionView.backgroundView.gestureRecognizers = #[tapRecognizer];

Swift - How to dismiss number keyboard after tapping outside of the textfield

How would you dismiss the keyboard from the UITextField when tapping outside of the keyboard. I have tried resignFirstResponder() and it only exits after typing one number. I have also tried textField.inputView = UIView.frame(frame: CGRectZero). I have seen many Obj-C verisons of what I'm asking but I need the Swift equivalent because I have no programming experience in Objective-C
Thank you for your time and patience.
The best way to add a tap gesture recognizer to the view and calling either resignFirstResponder() or self.view.endEditing(true). I prefer endEditing() since resignFirstResponder has to be done for each text field separately unlike endEditing which is done for the view itself.
In viewDidLoad, write the below code:
let tapRecognizer = UITapGestureRecognizer()
tapRecognizer.addTarget(self, action: "didTapView")
self.view.addGestureRecognizer(tapRecognizer)
Now write the didTapView method to dismiss the keyboard:
func didTapView(){
self.view.endEditing(true)
}
Now when you tap outside the keyboard on the main view of the controller, it will call the didTapView method and dismiss the keyboard.
Swift 3.x
The code in viewDidLoad should be:
let tapRecognizer = UITapGestureRecognizer()
tapRecognizer.addTarget(self, action: #selector(ViewController.didTapView))
self.view.addGestureRecognizer(tapRecognizer)
where ViewController should be the name of your view controller.
Thanks
Swift 3 tested and working
// dismiss keyboard on touch outside textfield
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for txt in self.view.subviews {
if txt.isKind(of: UITextField.self) && txt.isFirstResponder {
txt.resignFirstResponder()
}
}
}
Enjoy
Swift 2.3 tested and working
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for txt in self.view.subviews {
if txt.isKindOfClass(UITextField.self) && txt.isFirstResponder() {
txt.resignFirstResponder()
}
}
}
Enjoy
You could also use this method to dismiss the keyboard when pressing 'Return'
func textFieldShouldReturn(textField: UITextField!) -> Bool {
self.view.endEditing(true);
return false;
}
Make sure to set your delegate
If you don't want to define an extra method, there is a slightly simpler way that will also work
let tapRecognizer = UITapGestureRecognizer(target: self, action: "endEditing:")
view.addGestureRecognizer(tapRecognizer)
I found this code on a site and it works great for me!
//FUNCTION TO DISMISS THE KEYBOARD
func initializeHideKeyboard(){
//Declare a Tap Gesture Recognizer which will trigger our dismissMyKeyboard() function
let tap: UITapGestureRecognizer = UITapGestureRecognizer(
target: self,
action: #selector(dismissMyKeyboard))
//Add this tap gesture recognizer to the parent view
view.addGestureRecognizer(tap)
}
#objc func dismissMyKeyboard(){
//endEditing causes the view (or one of its embedded text fields) to resign the first responder status.
//In short- Dismiss the active keyboard.
view.endEditing(true)
}
Then just call this function in a button action or similar:
dismissMyKeyboard()

Resources