dismiss keyboard from all view hierarchy programmatically in swift - swift

I have view controller like screenshot below.
When I touch textfield, the keyboard shows up.
I want to dismiss keyboard when I tap,drag on any screen.
I tried to put this code in viewcontroller, but doesn't work.
func dismissKey() {
let tap: UITapGestureRecognizer = UITapGestureRecognizer( target: self, action: #selector(dismissKeyboard))
tap.cancelsTouchesInView = false
addGestureRecognizer(tap)
}
#objc func dismissKeyboard() {
endEditing(true)
resignFirstResponder()
}
but if I put this code in custom cell class type 1 ,it dismisses keyboard only when I tap on this cell.
how can I dismiss keyboard when I touch on any screen?

If you're trying to dismiss keyboard in UIViewController try:
#objc func dismissKeyboard() {
view.endEditing(true)
resignFirstResponder()
}

Related

Can't find which view triggered the tap gesture recognizer in my custom view

I know a lot of questions are answered for the issues like this but in my case, the common answers do not work.
I have a custom view which is a small view that appears above the active textfield to show the clipboard data so if the user wants that data in that textField, taps on my custom view so the clipboard text automatically pastes into that textField.
everything works fine when there is a single textField on the page. but if I add another textField, this custom view can't detect the correct textField to paste the text into it.
here is my code inside my customView to detect current textField
private func addTapGesture() {
let tap = UITapGestureRecognizer(target: self, action: #selector(tapAction))
tap.cancelsTouchesInView = true
tap.delegate = self
window?.addGestureRecognizer(tap)
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
if touch.view!.frame.contains(subviews.first!.frame) {
tapComple?(true)
} else {
tapComple?(false)
}
return true
}
I know that already other answers on the stackoverflow are saing to use this:
if touch.view == self
But it is not working in my case...
The demo project to see everything.
You need to detect if the rectangle contains the point which you touched. You can achieve that with the code below.
Change your gestureRecognizer(_:shouldRecieve:) method to the following:
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
if subviews.first?.frame.contains(touch.location(in: subviews.first)) == true {
print(true)
tapComple?(true)
} else {
print(false)
tapComple?(false)
}
return true
}
Result:
You don't need to do any calculations or listening gesture recognizer delegate.
Instead of that you can add tap gesture recognizer on your own view, on on the window. So all taps it receive - will be correct ones.
Also right now you're adding your view as subview to text field. This is really a bad practice and will stop this view from receiving taps.
Instead of that I suggest you adding it to to UIViewController view. To do so you need to pass two views into your LContextView: superview and anchorView on which you'll bind your constraints
private func configView(superView: UIView, anchorView: UIView, size: CGSize) {
removePreviusContexes(superView: superView)
superView.addSubview(self)
backgroundColor = .white
translatesAutoresizingMaskIntoConstraints = false
widthAnchor.constraint(equalToConstant: size.width).isActive = true
heightAnchor.constraint(equalToConstant: size.height).isActive = true
centerXAnchor.constraint(equalTo: anchorView.centerXAnchor).isActive = true
centerYAnchor.constraint(equalTo: anchorView.centerYAnchor, constant: -50).isActive = true
...
private func addTapGesture() {
let tap = UITapGestureRecognizer(target: self, action: #selector(tapAction))
addGestureRecognizer(tap)
}

How to single out and action a UITapGestureRecognizer for a UIView that is in the UIViewController.view that also has a UITapGestureRecognizer?

I have a UIView object that I have added a UITapGestureRecognizer. The main view also has a UITapGestureRecognizer that i use to hide the keyboard. How can i prioritise the tapGesture on the child UIView to do what i need to do? I would like, when tapping the child view to trigger the action associated with this tap, rather than the main views's gesture.
I have tried adding a double tap to the child view, to distinguish between the two gestures, but this just triggers the action for the main views's tap action.
var childView: UIView!
/**Tap screen event listener - to hide the keyboard*/
let tapGesture = UITapGestureRecognizer.init(target: self, action: #selector(hideKeyBaord))
self.view.addGestureRecognizer(tapGesture)
let doubleTap = UITapGestureRecognizer.init(target: self, action: #selector(doSomethingElse))
doubleTap.numberOfTouchesRequired = 2
childView.view.addGestureRecognizer(doubleTap)
One way is to implement the shouldReceiveTouch delegate method for tapGesture:
extension YourViewController : UIGestureRecognizerDelegate {
override func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
if gestureRecogniser == tapGesture {
// tapGesture should not receive the touch when the touch is inside the child view
let location = touch.location(in: childView)
return !childView.bounds.contains(location)
} else {
return true
}
}
}
And remember to set the delegate of tapGesture to self.

swift4 UISwipeGestureRecognizer Viewcontroller with large title and cells not working

I have a ViewController with large titles. In my ViewController are 2 cells. UISwipeGestureRecognizer is not working by swiping down. I want to call a searchController with this swipe-action in the titleView. Could the reason be the large title ?( with swipe down the title goes down and becomes greater, thats OK ). But my swipe action will not be recognized. Any ideas?
my code: - function called in viewDidLoad() in ViewController
func swipeSetup() {
let swipeDown = UISwipeGestureRecognizer(target: self, action: #selector(funcSwipedDown(sender:)))
swipeDown.direction = .down
self.view.addGestureRecognizer(swipeDown)
}
#objc func funcSwipedDown(sender: UISwipeGestureRecognizer){
Utils.displayAlert(title: "Info", message: "swipe down")
self.addNavigationbar() // func for adding search bar
}

UITableViewCell's RemoveGestureRecognizer method doesn't work in Swift, ios8, Xcode 7

I have a UITableView with static cells and grouped style in my UIViewController. I added a UIGestureRecognizer, that I can dismiss the Keyboard, but I want to except the UIGestureRecognizer for several UITableViewCells, because they have a functionality when they get selected.
My code:
The class - variable that I can use it everywhere in the code:
var tap:UITapGestureRecognizer = UITapGestureRecognizer()
My viewDidLoad() Method:
override func viewDidLoad() {
super.viewDidLoad()
self.tap = UITapGestureRecognizer(target: self, action: "DismissKeyboard")
tableView.addGestureRecognizer(tap)
}
And the Action of the UIGestureRecognizer:
func DismissKeyboard()
{
print("is here")
if(self.keyboardIsVisible)
{
view.endEditing(true)
self.refreshTableView()
}
}
I removed the Gesture Recognizer of one cell in the override func cellForRowAtIndexPath:
cell.removeGestureRecognizer(self.tap)
But when I tap this cell it still goes into the DismissKeyboard - Action...
You add your UITapGesgureRecognizer to tableView and you try remove from de cell. Try use tableView.removeGestureRecognizer(self.tap)
Instead of Adding Tap Gesture on TableView Cell or TableView. you can Add Custom UIButton on UITableViewCell and Add Target to it. You can then disable Table view's didSelectRowatIndexPath event. You can write your code on button click events.

Swift: Re-activating Tap Gesture on Disclosure Indicators

I have a Swift project that has a Table View Controller with multiple Static Cell Sections. Some cells have UITextFields and others have Accessory: Disclosure Indicators. I’ve implemented the following Swift code to dismiss the keyboard when the background is tapped:
override func viewDidLoad() {
super.viewDidLoad()
let tapGesture = UITapGestureRecognizer(target: self, action: Selector("hideKeyboard"))
tapGesture.cancelsTouchesInView = true
tableView.addGestureRecognizer(tapGesture)
}
func hideKeyboard() {
tableView.endEditing(true)
}
This works great for releasing the keyboard on tapping the background, but it also removed the tap gesture for the Disclosure Indicators (swipe still works). Does anyone know how to re-activate the tap gesture for the Disclosure Indicators cells after implementing this hideKeyboard() function?
Keep a reference to the gesture recognizer and remove it from the view when you hide the keyboard.
class YourController: UITableViewController {
let tapGesture: UITapGestureRecognizer = {
let tg = UITapGestureRecognizer(target: self, action: "hideKeyboard")
tg.cancelsTouchesInView = true
return tg
}()
override func viewDidLoad() {
super.viewDidLoad()
tableView.addGestureRecognizer(tapGesture)
}
func hideKeyboard() {
tableView.endEditing(true)
tableView.removeGestureRecognizer(tapGesture)
}
}