Dismissing the keyboard in a UIScrollView

IosObjective CSwiftUiscrollviewKeyboard

Ios Problem Overview


Alright, I have a couple of UITextFields and UITextViews inside a UIScrollView, and I'd like to set the keyboard to disappear whenever the scrollview is touched or scrolled (except when you touch down inside the text field/view, of course).

My current attempt at doing this is replacing the UIScrollView with a subclass, and setting it to call a removeKeyboard function (defined inside the main view controller) inside the touchesBegan method. However, this only removes the keyboard for a normal touch, not when the view is simply scrolled. So, what's the best way to remove the keyboard inside a UIScrollView?

Thanks in advance for your help.

Ios Solutions


Solution 1 - Ios

Here is the cleanest way to achieve this in iOS 7.0 and above.

scrollView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;

Or

scrollView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;

In Swift:

scrollView.keyboardDismissMode = .onDrag

Or

scrollView.keyboardDismissMode = .interactive

Solution 2 - Ios

Bit late but if anyone else is searching an answer to this problem, this is how I have gone about solving it:

  1. Create a tap gesture recognizer with a target callback method to dismiss your keyboard using resignFirstResponder on all your fields.

  2. Add the tap gesture to the scrollview.

Here's an example:

UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];

// prevents the scroll view from swallowing up the touch event of child buttons
tapGesture.cancelsTouchesInView = NO;    

[pageScrollView addGestureRecognizer:tapGesture];

[tapGesture release];

...

// method to hide keyboard when user taps on a scrollview
-(void)hideKeyboard
{
    [myTextFieldInScrollView resignFirstResponder];
}

Solution 3 - Ios

Although the essence is the same, I prefer less code.

Setting the keyboard to disappear when the scrollView is scrolled in Attributes inspector:

make keyboard disappear when scrollView is scrolled

Then disappear keyboard when scrollView is tapped:

  1. Drag a Tap Gesture Recognizer onto your scrollView
  2. Ctrl-Drag
  3. Make an action
  4. Only one line in the action —— scrollView.endEditing(true). If you are using Objective-C, [self.scrollView endEditing: YES];

Solution 4 - Ios

In Swift:

Bit late but if anyone else is searching an answer to this problem, this is how I have gone about solving it:

  1. Create a tap gesture recognizer with a target callback method to dismiss your keyboard using resignFirstResponder on all your fields.

  2. Add the tap gesture to the scrollview.

Here's an example:

import UIKit

class ViewController: UIViewController {

    @IBOutlet var t1: UITextField!
    @IBOutlet var t2: UITextField!
    @IBOutlet var t3: UITextField!
    @IBOutlet var t4: UITextField!
    
    @IBOutlet var srcScrollView: UIScrollView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        let tapGesture: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "hideKeyboard")
        
        // prevents the scroll view from swallowing up the touch event of child buttons
        tapGesture.cancelsTouchesInView = false
        
        srcScrollView.addGestureRecognizer(tapGesture)
    }
    
    func hideKeyboard() {
        t1.resignFirstResponder()
        t2.resignFirstResponder()
        t3.resignFirstResponder()
        t4.resignFirstResponder()
    }
}

Solution 5 - Ios

Look at keyboardDismissMode property of UIScrollView.

// will hide keyboard when your text field is about to go beyond the keyboard.
vwScrollView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;

// will hide keyboard instantly once the scroll view started scrolling by user.
vwScrollView.keyboardDismissMode = UIScrollViewKeyboardDismissOnDrag;

// If you need to hide keyboard on tap of scroll view,consider adding a tap gesture or sub class and override touchesbegan: method.

Swift Version

vwScrollView.keyboardDismissMode = .interactive
vwScrollView.keyboardDismissMode = .onDrag

Solution 6 - Ios

Try This

[self.selectedViewController.view endEditing:YES];

Solution 7 - Ios

Create a extension class for hiding keyboard when touches scrollview/view anywhere

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)
  }
}

And call this method in viewDidLoad like

override func viewDidLoad() {
  super.viewDidLoad()
  self.hideKeyboardWhenTappedAround()    
}

Solution 8 - Ios

A bit late but if anyone else is searching an answer to this problem with Swift 3:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    view.endEditing(true)
}

Solution 9 - Ios

When I added the gesture to a subclass of UIScrollView, I was having problems with the various gestures in my view tree interfering with each other, such as being able to click on subviews, scroll the view, and have the keyboard dismiss in all cases. I came up with this solution, which can be setup from a superclass of UIScrollView or from a UIViewController.

The DismissKeyboardTapGesture class uses ARC, works with any text fields under the view, and doesn't take over any clicks from subviews like buttons. Also takes advantage of iOS7 scrolling effect to dismiss keyboard.

Setting up from UISScrollView superclass:

    _dismissKeyboard = [[DismissKeyboardTapGesture alloc] initWithView:self];

or from UIViewController:

    _dismissKeyboard = [[DismissKeyboardTapGesture alloc] initWithView:self.view];

Here is the class:

@interface DismissKeyboardTapGesture : NSObject <UIGestureRecognizerDelegate>

@end

@implementation DismissKeyboardTapGesture

- (id)initWithView:(UIView *)view
{
    self = [super init];
    if (self) {
        UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap:)];
        singleTap.cancelsTouchesInView = NO;
        singleTap.delegate = self;
        [view addGestureRecognizer:singleTap];

        if ([view respondsToSelector:@selector(setKeyboardDismissMode:)]) {
            // Bonus effect to dismiss keyboard by scrolling
            ((UIScrollView *)view).keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;
        }
    }
    return self;
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    // Don't stop any existing gestures in our view from working
    if (otherGestureRecognizer.view == gestureRecognizer.view) {
        return YES;
    }
    return NO;
}

- (void)singleTap:(UIGestureRecognizer*)gestureRecognizer
{
    // Close keyboard for any text edit views that are children of the main view
    [gestureRecognizer.view endEditing:YES];
}

@end


Solution 10 - Ios

Try this scroll view delegate method -

link delegate in IB to scroll view and then cop this code (modify as per your need).

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{         
//sample code    
    [challengeABallotComponent.voterNameTextField resignFirstResponder];
    [challengeABallotComponent.ballotNumberTextField resignFirstResponder];
    [locationInformation.pollingLocation resignFirstResponder];
}

This should work. You can try other delegate methods too like

   -(void)scrollViewDidScroll: (UIScrollView *)scrollView 
{
//do your stuff
}

Solution 11 - Ios

scrollView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;

Solution 12 - Ios

    extension UIView{
    //Set tag via storyboard 
    func keyboardDissmissInteractiveMode(_ tag:Int){
        if let scrollView = self.viewWithTag(tag) as? UIScrollView{
            scrollView.keyboardDismissMode = .interactive
        }
        if let tableview = self.viewWithTag(tag) as? UITableView{
            tableview.keyboardDismissMode = .interactive
        }
    }
    
    func keyboardDissmissOnDragMode(_ tag:Int){
        if let scrollView = self.viewWithTag(tag) as? UIScrollView{
            scrollView.keyboardDismissMode = .onDrag
        }
        if let tableview = self.viewWithTag(tag) as? UITableView{
            tableview.keyboardDismissMode = .onDrag
        }
    }
    
    
    func keyboardDissmissInteractiveMode(_ view:UIView){
        if let scrollView = view as? UIScrollView{
            scrollView.keyboardDismissMode = .interactive
        }
        if let tableview = view as? UITableView{
            tableview.keyboardDismissMode = .interactive
        }
    }
    
    func keyboardDissmissOnDragMode(_ view:UIView){
        if let scrollView = view as? UIScrollView{
            scrollView.keyboardDismissMode = .onDrag
        }
        if let tableview = view as? UITableView{
            tableview.keyboardDismissMode = .onDrag
        }
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNicholas1024View Question on Stackoverflow
Solution 1 - IosPeiView Answer on Stackoverflow
Solution 2 - IosZhangView Answer on Stackoverflow
Solution 3 - Iosfujianjin6471View Answer on Stackoverflow
Solution 4 - IosKing-WizardView Answer on Stackoverflow
Solution 5 - IosNaresh Reddy MView Answer on Stackoverflow
Solution 6 - IosSaad Ur RehmanView Answer on Stackoverflow
Solution 7 - Ioschandra1234View Answer on Stackoverflow
Solution 8 - IosJorge CasariegoView Answer on Stackoverflow
Solution 9 - IosSkotchView Answer on Stackoverflow
Solution 10 - Iosuser1140780View Answer on Stackoverflow
Solution 11 - Iosvignesh.PView Answer on Stackoverflow
Solution 12 - Iosjethava yogeshView Answer on Stackoverflow