How to dismiss keyboard when user tap other area outside textfield? - ios

today I tried to run my code on my iPod (iOS 6.1.3) and I found something interesting here...
first, when I tap on textfield the keyboard shows up but it won't hide when I tap somewhere else outside textfield.
so I decided to Googling and found this solution :
_fieldEmail.delegate = self;
_fieldEmail.returnKeyType = UIReturnKeyDone;
_fieldPassword.delegate = self;
_fieldPassword.returnKeyType = UIReturnKeyDone;
_fieldRegisterName.delegate = self;
_fieldRegisterName.returnKeyType = UIReturnKeyDone;
_fieldRegisterEmail.delegate = self;
_fieldRegisterEmail.returnKeyType = UIReturnKeyDone;
_fieldRegisterPassword.delegate = self;
_fieldRegisterPassword.returnKeyType = UIReturnKeyDone;
it works... it gives a 'DONE' button on the bottom of keyboard and now the keyboard can be hidden by pressing it.
but I have 2 problems here :
the keyboard only hide when 'DONE' button is tapped. not by tapping other area outside text field. I don't know if this normal on iOS world, but usually I see lot of apps don't act like this.
is there any way to loop this process so I don't have manually add that delegate one by one of all textfield that I have? how to do that?
that's all I need to know

The below code will work on all the components in the UIView for all the UITextField
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for (UIView * txt in self.view.subviews){
if ([txt isKindOfClass:[UITextField class]] && [txt isFirstResponder]) {
[txt resignFirstResponder];
}
}
}
OR
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}

Simply add an UITapGestureRecogniser to your view that will lead to calling resignFirstResponder
In viewDidLoad :
UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(hideKeyBoard)];
[self.view addGestureRecognizer:tapGesture];
And then :
-(void)hideKeyBoard {
[yourTextField resignFirstResponder];
}
2.You could subclass UITextField but unless you have 1000 textFields it is ok to do like you currently do.

This is regards to Swift programming for Xcode 6.0.1
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
let tapRecognizer = UITapGestureRecognizer(target: self, action: "handleSingleTap:")
tapRecognizer.numberOfTapsRequired = 1
self.view.addGestureRecognizer(tapRecognizer)
}
func handleSingleTap(recognizer: UITapGestureRecognizer) {
self.view.endEditing(true)
}

Use Either
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
[self.view addGestureRecognizer:singleTap];
and code of method
-(void)handleSingleTap:(UITapGestureRecognizer *)sender{
[self.TextFiledName resignFirstResponder];
}
OR _ And The best Other option is
Just add
[self.view endEditing:YES];
And key board will hide when you tapped anywhere from view:)

Dismissing the keyboard
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self.view endEditing:YES];
[super touchesBegan:touches withEvent:event];
}

Simple,
Use IQKeyboardManager and put this line of code in AppDelegate.m
[[IQKeyboardManager sharedManager] setShouldResignOnTouchOutside:YES];

What I usually do is call
[field resignFirstResponder];
from an invisible button over the view. I'm sure theres a nicer way to do it. It's been a while since I've done this in an app.

Here's how I do it:
In the myView's .h file:
#property (strong) UITextField * savedTextField;
In the myView's .m file:
#implementation myView
#synthesize savedTextField;
In the myView's init routine:
[self setSavedTextField: nil];
In the myView's textField delegate area I save the id of whichever textField is currently activating:
- (BOOL) textFieldShouldBeginEditing: (UITextField *) textField
{
[self setSavedTextField: textField];
.
.
.
return( YES );
}
And in the myView's routine that routes all the traffic for the other controls when they are accessed, I have code that looks to see if a textField was active and, if one was, it calls on it to resign its FirstResponder status and then drops a nil into the savedTextField property:
- (void) handleCtrlEvents: (UIControl *) aCtrl
{
if ( [self savedTextField] != nil )
{
[[self savedTextField] resignFirstResponder];
[self setSavedTextField: nil];
}
.
.
.
}
This works cleanly for me.

I ran into the exact same problem. Usually what you want is, that wherever you click inside your App (which is displayed in your main / current UIView) but not on the keyboard to close it. After searching the web for a smart solution and testing several, I think it is the best to extend/subclass/implement the UIGestureRecognizerDelegate
Since many controls such as UITableView etc. can respond to gestures (select, scrolling etc.) and if you simply add a UITapGestureRecognizer to the whole (main-)ViewController's view to close the keyboard, the user experience is not the best, since the user needs to tap twice if he didn't intend to close the keyboard but e.g. select a row from a UITableView inside the App's current "main" View.
Since I am quite new to the whole iOS and swift thing and swift code examples are rare, here's my full keyboard control snipped:
class ViewController: UIViewController, UIGestureRecognizerDelegate {
override func viewDidLoad(){
self.initializeCloseKeyboardTap()
}
func initializeCloseKeyboardTap() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "onKeyboardOpen:", name: UIKeyboardDidShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "onKeyboardClose:", name: UIKeyboardDidHideNotification, object: nil)
let tapRecognizer = UITapGestureRecognizer(target: self, action: "handleOnTapAnywhereButKeyboard:")
tapRecognizer.delegate = self //delegate event notifications to this class
self.view.addGestureRecognizer(tapRecognizer)
}
func onKeyboardClose(notification: NSNotification) {
println("keyboardClosed")
}
func onKeyboardOpen(notification: NSNotification) {
println("keyboardOpen")
}
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
self.view.endEditing(true)
return false
}
you can nest it inside the ViewController and call initiallizeCloseKeyboardTa() in viewDidLoad implementation... It also implements a norfication observer to receive events as soon as the keyboard (finished to be) opened or closed via NSNotificationCenter UIKeyboardDidShowNotification and UIKeyboardDidHideNotification
Hope that save's other people some time :-)

|*| Dismissing the UITextField’s Keyboard : override the method touchesBegan:withEvent: for the ViewController
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
{
view.endEditing(true)
super.touchesBegan(touches, withEvent: event)
}
|OR|
override func viewDidLoad()
{
super.viewDidLoad()
// For tapping outside text box
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(DismisKeyPadFnc)))
}
// For tapping outside text box
func DismisKeyPadFnc()
{
view.endEditing(true)
}
|*| Dismissing the UITextField’s Keyboard on induvidual textbox :
class NamVcc: UIViewController, UITextFieldDelegate
{
#IBOutlet var NamTxtBoxVid: UITextField!
override func viewDidLoad()
{
super.viewDidLoad()
// For hitting return key
NamTxtBoxVid.delegate = self
// For tapping outside text box
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(DismisKeyPadFnc)))
}
/* For hitting return key */
func textFieldShouldReturn(NamTxtBoxPsgVid: UITextField) -> Bool
{
NamTxtBoxPsgVid.resignFirstResponder()
return true
}
/* For tapping outside text box */
func DismisKeyPadFnc()
{
view.endEditing(true)
}
}
|*| Implementing Next button Click :
1) You will be needing to set the tags in the incremental sequence of the textfields in xib/Storyboard or in code.
2) Set the delegate for each of the textfields.
3) Then paste the following code in your view controller to have the desired effect:
func textFieldShouldReturn(TxtBoxPsgVar: UITextField) -> Bool
{
let NxtTxtBoxTagVal : Int = TxtBoxPsgVar.tag + 1
let NxtTxtBoxVal: UIResponder? = TxtBoxPsgVar.superview?.superview?.viewWithTag(NxtTxtBoxTagVal)
if let TxtBoxVal = NxtTxtBoxVal
{
// Found next responder, so set it.
TxtBoxVal.becomeFirstResponder()
}
else
{
// Not found, so remove keyboard.
TxtBoxPsgVar.resignFirstResponder()
}
return true
}

I prefer IQKeyboardManager. You can simply handle keyboard in any state. To active IQKeyboard just add one line in AppDelegate and to dismiss keyboard on outside touch add code as below,
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
IQKeyboardManager.shared.enable = true
IQKeyboardManager.shared.shouldResignOnTouchOutside = true
return true
}

I think
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
is convenient but not the best solution.
and the TapGestureRecongnizer is better but hard to use,you have to set delegates and add and remove the Recongnizer.
So I wrote a simple subclass which can be easily used:
class TapHideTextField: UITextField {
override func awakeFromNib() {
super.awakeFromNib()
tapGr = UITapGestureRecognizer(target: self, action:"tap")
NSNotificationCenter.defaultCenter().addObserver(self, selector: "didBeginEditing", name:UITextFieldTextDidBeginEditingNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "didEndEditing", name:UITextFieldTextDidEndEditingNotification, object: nil)
}
deinit{
NSNotificationCenter.defaultCenter().removeObserver(self)
}
var tapGr:UITapGestureRecognizer!
func tap(){
self.endEditing(true)
}
func didBeginEditing(){
self.superview!.addGestureRecognizer(tapGr)
}
func didEndEditing(){
self.superview!.removeGestureRecognizer(tapGr)
}
}
you should concern about the superview and the cancelTouchesInView property.
or in GitHub:https://github.com/lilidan/TapHideText/blob/master/TapHideTextField.swift

If you're using scroll view (or table view) controller, add these lines there:
override func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
view.endEditing(true)
}

-(void) textFieldDidBeginEditing: (UITextField *) textField{
[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(DismissKeyboard:)]];
}
-(void) DismissKeyboard:(UITapGestureRecognizer *) sender{
[self.view endEditing:YES];
[self.view removeGestureRecognizer:sender];
}

Related

Hide keyboard from search bar in CollectionViewController

While my problems seems easy to solve I cannot do it myself.
Basically I got my CollectionViewController that holds all of my data and I've included within it a search bar which filters items from my collection depending on what the user writes.
When an user taps on any item it leads them to another view and so on.
And when the user taps on the search bar, the keyboard shows up and I'd like to hide it whenever the user decides to tap somewhere else.
While I can do that it turns out that every time I hide the keyboard with the methods I found, it also prevents the user from going further into my application, in fact it's not longer possible to go to another view after tapping on them.
Here's what I did :
My CollectionViewController.swift
override func viewDidLoad() {
super.viewDidLoad()
// Setup search bar/collection view
self.collectionView?.dataSource = self
searchBar.delegate = self
searchBar.sizeToFit()
searchBar.placeholder = "Search"
navigationItem.titleView = searchBar
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "dismissKeyboard")
view.addGestureRecognizer(tap)
}
func dismissKeyboard() {
searchBar.resignFirstResponder()
}
I also tried many things found here without success. Somehow even if I've included the UIGestureRecognizerDelegate in my file some delegate listed there aren't triggered when I tap somewhere. For example the delegate gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool doesnt work.
I can see the logic right here, but it's just impossible to find any fix that doesn't break the collectionview.
Any help is appreciated, thank you.
Please use below solution for both Objective-c & Swift, I hope it will work for you dear
Swift
create variable let tap = UITapGestureRecognizer() and in viewDidLoad method write below code.
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: nil);
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: nil);
}
And paste below code for further implementation of methods:
func keyboardWillShow(notification: NSNotification) {
tap = UITapGestureRecognizer(target: self, action: "dismissKeyboard")
view.addGestureRecognizer(tap)
}
func keyboardWillHide(notification: NSNotification) {
view.removeGestureRecognizer(tap)
}
(Objective-c) First of all create UITapGestureRecognizer *tap variable and in viewDidLoad method paste below code.
//Notifications for keyBoardShow and keyBoradHide
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
And paste below code:
- (void)keyboardWillShow:(NSNotification *)notif {
//Add tap gesture here
tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
}
- (void)keyboardWillHide:(NSNotification *)notif {
//Remove tap gesture
[self.view removeGestureRecognizer:tap];
}
-(void)dismissKeyboard {
[yourSearchBar resignFirstResponder];
}
#CroiSciento dear check this solution.
check this out
override func scrollViewWillBeginDragging(scrollView: UIScrollView) {
searchBar.resignFirstResponder()
}
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
searchBar.resignFirstResponder()
}

Remove view when tapped outside

I have a UIView, that I have appear when a button is tapped, I am using it as a custom alert view essentially. Now when the user taps outside the custom UIView that I added to the main view, I want to hide the cusomt view, I can easily do this with customView.hidden = YES; but how can I check for the tap outside the view?
Thanks for the help
There are 2 approaches
First approach
You can set a tag for your custom view:
customview.tag=99;
An then in your viewcontroller, use the touchesBegan:withEvent: delegate
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
if(touch.view.tag!=99){
customview.hidden=YES;
}
}
Second approach
It's more likely that every time you want to popup a custom view, there's an overlay behind it, which will fill your screen (e.g. a black view with alpha ~0.4). In these cases, you can add an UITapGestureRecognizer to it, and add it to your view every time you want your custom view to show up. Here's an example:
UIView *overlay;
-(void)addOverlay{
overlay = [[UIView alloc] initWithFrame:CGRectMake(0, 0,self.view.frame.size.width, self.view.frame.size.height)];
[overlay setBackgroundColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:0.5]];
UITapGestureRecognizer *overlayTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(onOverlayTapped)];
[overlay addGestureRecognizer:overlayTap];
[self.view addSubview:overlay];
}
- (void)onOverlayTapped
{
NSLog(#"Overlay tapped");
//Animate the hide effect, you can also simply use customview.hidden=YES;
[UIView animateWithDuration:0.2f animations:^{
overlay.alpha=0;
customview.alpha=0;
}completion:^(BOOL finished) {
[overlay removeFromSuperview];
}];
}
Like in the answer of FlySoFast, I tried first approach and it worked I just shared to swift version of it. You can tag it of your custom view and the check the that view touched or not so we achieved our solution I guess.In the below I assign tag value of my custom view to 900.
customview.tag = 900
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first!
if touch.view?.tag != 900 {
resetMenu()
}
}
I hope this answer will help to you
When you presenting custom alert view, add that custom alert view in to another full screen view, make that view clear by setting its backgroundColor clear. Add full screen view in main view, and add tapGesture in fullScreen invisible view, when ever it gets tap remove this view.
But if you will do this it will dismiss view even when you touch custom alert view for that you need to set delegate of tapGesture and implement this method
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if ([touch.view isDescendantOfView:self.customAlertView])
{
return NO;
}
return YES;
}
with using function pointInside in Swift:
override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
if let view = customView {
//if UIView is open open
let newPoint = self.convertPoint(point, toView: view)
let pointIsInsideGenius = view.pointInside(newPoint, withEvent: event)
// tapping inside of UIView
if pointIsInsideGenius {
return true
} else {
// if tapped outside then remove UIView
view.removeFromSuperview()
view = nil
}
}
}
return false
}
You can use this library: https://github.com/huynguyencong/EzPopup
Init a PopUpController the view that you want to dismiss it when tap outside
let popup = PopupViewController(contentView: viewNeedToRemoveWhenTapOutside, position: .bottomLeft(position))
present(popup, animated: true, completion: nil)
You can make this by the way. The main tricks are a button that wraps the full screen behind your custom view. When you click on the button you simply dismiss your custom view. Here is the complete code.
Here is the complete custom uiview class
import Foundation
import UIKit
class CustomAlartView: UIView {
static let instance = CustomAlartView()
#IBOutlet var parentView: UIView!
#IBOutlet weak var mainView: UIView!
#IBOutlet weak var userInput: UITextField!
override init(frame: CGRect) {
super.init(frame: frame)
Bundle.main.loadNibNamed("CustomAlartView", owner: self, options: nil)
setupView()
}
//initWithCode to init view from xib or storyboard
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
// setupView()
}
#IBAction func tappedCancel(_ sender: Any) {
parentView.removeFromSuperview()
}
#IBAction func tappedOk(_ sender: Any) {
if userInput.text == "" {
print("\(userInput.text)")
}
else{
parentView.removeFromSuperview()
}
}
#IBAction func tappedOutside(_ sender: Any) {
print("click outside")
parentView.removeFromSuperview()
}
//common func to init our view
private func setupView() {
parentView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
parentView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
mainView.layer.shadowColor = UIColor.gray.cgColor
mainView.layer.shadowOpacity = 1
mainView.layer.shadowOffset = CGSize(width: 10, height: 10)
mainView.layer.shadowRadius = 10
mainView.layer.cornerRadius = 15
mainView.layer.masksToBounds = true
}
enum alartType {
case success
case failed
}
func showAlart() {
UIApplication.shared.keyWindow?.addSubview(parentView)
}
}

How to hide the keypad after use

Hei, is there an easy way to add - that after the input into a text field and pressing a button the keypad is disappearing from the screen?
I found here this answer: in button action routine write [yourTextField resignFirstResponder]. it will hide your keyboard.
But I dont get it where to place that code [yourTextField resignFirstResponder]
Thanks for help!
If you simply want to dismiss the keyboard when the user presses the return key, simply add this to viewDidLoad in order to receive delegate callbacks from your textfield:
- (void)viewDidLoad
{
[super viewDidLoad];
self.myTextfield.delegate = self;
}
And then implement this method that hides the keyboard when the user presses the return key:
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return NO;
}
And in Swift:
override func viewDidLoad() {
super.viewDidLoad()
myTextfield.delegate = self
}
func textFieldShouldReturn(textField: UITextField!) -> Bool {
textField.resignFirstResponder()
return false
}
If you're not pressing the return key, but your own UIButton, you'll have to do something like this:
#IBAction func findBudget(sender: AnyObject) {
myTextfield.resignFirstResponder()
// .. rest of your code.
}

Add UITapGestureRecognizer to UITextView without blocking textView touches

How can I add a UITapGestureRecognizer to a UITextView but still have the touches getting through to the UITextView as normal?
Currently as soon as I add a custom gesture to my textView it blocks the tap for UITextView default actions like positioning the cursor.
var tapTerm:UITapGestureRecognizer = UITapGestureRecognizer()
override func viewDidLoad() {
tapTerm = UITapGestureRecognizer(target: self, action: "tapTextView:")
textView.addGestureRecognizer(tapTerm)
}
func tapTextView(sender:UITapGestureRecognizer) {
println("tapped term – but blocking the tap for textView :-/")
…
}
How can I process taps but keep any textView behaviour like cursor positioning as is?
To do that make your view controller adopt to UIGestureRecognizerDelegate and override should recognize simultaneously with gesture recognizer method like:
override func viewDidLoad() {
tapTerm = UITapGestureRecognizer(target: self, action: "tapTextView:")
tapTerm.delegate = self
textView.addGestureRecognizer(tapTerm)
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
In case anyone came here looking for #Zell B.'s answer in Objective C, here's the code:
- (void)viewDidLoad {
[super viewDidLoad];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(textViewTapped:)];
tap.delegate = self;
tap.numberOfTapsRequired = 1;
[self.textView addGestureRecognizer:tap];
}
- (void)textViewTapped:(UITapGestureRecognizer *)tap {
//DO SOMTHING
}
#pragma mark - Gesture recognizer delegate
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
PS: Don't forget < UIGestureRecognizerDelegate >
Swift 4.2
The following steps allows me to escape a full-screen UITextView with a tap, whilst allowing to scroll the contents of the UITextView:
Disconnected the UIGestureRecognizer from the UITableView.
Made a CustomTextView: UITextView.
Added a 'sender' var to the particular UIViewController with the CustomTextView.
Trap for 'Touches Ended...'
Call for an excape function within the sender UIViewController.
class CustomTextView: UITextView {
var sender: DocViewController?
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
if let controller = sender {
controller.handleSwipeGesture()
}
}
}
I can either scroll the contents of the UITextView or merely tap to exit.
The 'sender' is set from the hosting UIViewController at creation.
Somehow I could not assign a delegate inside UIView so I came up with a button solution.
I insert a button that completely covers the textView and when tapped on textViewButton I do resign the button so textView shows.
#IBAction func textViewTapped(_ sender: UIButton) {
self.placeholderLabel.isHidden = true
self.textViewButton.resignFirstResponder()
}

iOS Hide keyboard when tapping outside of an uitextfield, located in a subview?

I am new at this (also i am from argentina, sorry for my basic english), and i REALLY don't know what to do with this problem. I have a view, that contains a UIScrollView to scroll the View, and inside i have a subView that contains a lot of UITextField. The point is to hide keyboard when I touch outside of the UITextField, but I think the touch event is not triggered (I don't know why, maybe you can help me). I am also a newbie in iOS, but I am learning! Thanks!
EDIT: First, thanks to all for answering! For all who said to disable usar interaction, it works for UITextFields, but now i can't interact with UITable's inside de subview! Any help?
try this
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}
or this
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for (UIView * youtxtfl in self.view.subviews){
if ([youtxtfl isKindOfClass:[UITextField class]] && [youtxtfl isFirstResponder]) {
[youtxtfl resignFirstResponder];
}
}
}
The Scroll View is going to intercept the gesture recogniser, you will need to disable the user interaction on the view AFTER you click on the text field.
You can do this via;
scrollView.userInteractionEnabled = NO;
Swift:
The next solution is for UITextView, but you can modify it for UITextField
1) Add keyboardWillShow event handler in the view controller that contains the field and save a reference to the field
/**
Listen keyboard events
:param: animated the animation flag
*/
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
initNavigation()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil)
}
/**
Remove self as keyboard listener
:param: animated the animation flag
*/
override func viewWillDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
}
/**
Save reference to focused textView
:param: sender the sender
*/
func keyboardWillShow(sender: AnyObject){
if self.searchTextField?.isFirstResponder() ?? false {
KeyboardDismissingUIViewTarget = self.searchTextField
}
}
/**
Clean KeyboardDismissingUIViewTarget
:param: sender the sender
*/
func keyboardWillHide(sender: AnyObject){
KeyboardDismissingUIViewTarget = nil
}
2) Use custom class for top most UIView:
/// the target view (textView) which should not dismiss the keyboard
var KeyboardDismissingUIViewTarget: UIView?
/**
* Custom class for top view that dismisses keyboard when tapped outside the given textView or textField
*
* #author Alexander Volkov
* #version 1.0
*/
class KeyboardDismissingUIView: UIView {
override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
if let targetView = KeyboardDismissingUIViewTarget as? UITextView {
// Convert the point to the target view's coordinate system.
// The target view isn't necessarily the immediate subview
let pointForTargetView = targetView.convertPoint(point, fromView: self)
if CGRectContainsPoint(targetView.bounds, pointForTargetView) {
return targetView.hitTest(pointForTargetView, withEvent: event)
}
else {
KeyboardDismissingUIViewTarget = nil
targetView.resignFirstResponder()
return nil
}
}
return super.hitTest(point, withEvent: event)
}
}
Hope this will help you :)
- (void)viewDidLoad
{
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
}
-(void)dismissKeyboard
{
[svScrollView setContentOffset:CGPointMake(0, 0) animated:YES];
[self resignFirstResponder];
}
There is property in XIB file, please find below screenshot.

Resources