Reputation: 2061
In my app I want to hide keyboard when I start scrolling any UITableView or scroll view.
Upvotes: 146
Views: 78151
Reputation: 39470
You can do this right in Interface Builder. Select your UITableView
and open the Attributes Inspector. In the Scroll View section set the Keyboard field to Dismiss on Drag.
this works perfectly for both any scroll view and any table view
there is absolutely no need whatsoever to override anything. any answers which mention overriding something, are simply, completely wrong
the feature is entirely built in to iOS, and as of recent versions works perfectly. simply turn it on. there is nothing else to do.
you can do it on storyboard as in the image, or in code it is just tableView.keyboardDismissMode = .onDrag
. it is exactly the same thing, code or storyboard.
Upvotes: 137
Reputation: 291
With Swift 5
To hide the keyboard when scrolling the TableView and stop editing properly, we still need to combine two types of answers:
ViewDidLoad()
code (as Pei explained) for instance:tableView.keyboardDismissMode = .onDrag
UITableViewController
class override func scrollViewDidScroll(_ scrollView: UIScrollView) {
if !tableView.isDecelerating {
view.endEditing(true)
}
}
Upvotes: 10
Reputation: 11643
Here is the cleanest way to achieve this in iOS 7.0 and above:
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
Or to dismiss interactively when touching:
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;
Or in Swift:
tableView.keyboardDismissMode = .onDrag
To dismiss interactively:
tableView.keyboardDismissMode = .interactive
Upvotes: 468
Reputation: 548
After iOS 7, you can simple use the tableview property
Swift 3.0+
myTableView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.OnDrag
ObjectiveC
myTableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
For earlier versions, implementing the scroll view delegate could work.
func scrollViewDidScroll(_ scrollView: UIScrollView) {
view.endEditing(true)
}
Upvotes: 1
Reputation: 1578
Working solution without writing single line of code in your Controller:
As your question is to handle the hide keyboard with one condition only (on scroll). But here I am recommending one solution to handle textfield and keyboard together which works like charm for UIViewController, UITableView and UIScrollView. The interesting fact is that You do not need to write any single line of code.
Here you go: TPKeyboardAvoiding - An awesome solution to handle keyboard and scroll
Upvotes: 0
Reputation: 25294
Hide keyboard programmatically when scroll UITableView in Swift 3
xCode 8.2.1, swift 3
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if !tableView.isDecelerating {
view.endEditing(true)
}
}
ViewController
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var searchBar: UISearchBar!
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
}
}
// MARK: - UITableViewDataSource
extension ViewController: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 100
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: nil)
cell.textLabel?.text = "Title"
cell.detailTextLabel?.text = "\(indexPath)"
return cell
}
}
// MARK: - UITableViewDelegate
extension ViewController: UITableViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if !tableView.isDecelerating {
view.endEditing(true)
}
}
}
StoryBoard
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="stackoverflow_4399357" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<searchBar contentMode="redraw" translatesAutoresizingMaskIntoConstraints="NO" id="wU1-dV-ueB">
<rect key="frame" x="0.0" y="20" width="375" height="44"/>
<textInputTraits key="textInputTraits"/>
</searchBar>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" keyboardDismissMode="interactive" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="L52-4c-UtT">
<rect key="frame" x="0.0" y="64" width="375" height="603"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</tableView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="wU1-dV-ueB" firstAttribute="bottom" secondItem="L52-4c-UtT" secondAttribute="top" id="0WF-07-qY1"/>
<constraint firstAttribute="trailing" secondItem="wU1-dV-ueB" secondAttribute="trailing" id="3Mj-h0-IvO"/>
<constraint firstItem="wU1-dV-ueB" firstAttribute="leading" secondItem="L52-4c-UtT" secondAttribute="leading" id="8W5-9j-2Rg"/>
<constraint firstItem="wU1-dV-ueB" firstAttribute="trailing" secondItem="L52-4c-UtT" secondAttribute="trailing" id="crK-dR-UYf"/>
<constraint firstItem="wU1-dV-ueB" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leading" id="mPe-bp-Dxw"/>
<constraint firstItem="L52-4c-UtT" firstAttribute="bottom" secondItem="wfy-db-euE" secondAttribute="top" id="oIo-DI-vLh"/>
<constraint firstItem="wU1-dV-ueB" firstAttribute="top" secondItem="y3c-jy-aDJ" secondAttribute="bottom" id="tVC-UR-PA4"/>
</constraints>
</view>
<connections>
<outlet property="searchBar" destination="wU1-dV-ueB" id="xJf-bq-4t9"/>
<outlet property="tableView" destination="L52-4c-UtT" id="F0T-yb-h5r"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-79.200000000000003" y="137.18140929535232"/>
</scene>
</scenes>
</document>
Upvotes: 0
Reputation: 1810
Just to add an update to the answers above. The below worked for me in Swift 1.2
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.OnDrag
or
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.Interactive
Upvotes: 44
Reputation:
Not sure why you need to subclass UITableView for this.
In the view controller that contains the plain UITableView, try adding this:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
[searchBar resignFirstResponder];
}
Upvotes: 149