滚动 UITableView 时隐藏键盘

在我的应用程序我想隐藏键盘时,我开始滚动 UITableView。我在互联网上搜索这个问题,大多数答案是子类化 UitableView ( http://stackoverflow.com/questions/3499810/tapping-a-uiscrollview-to-hide-the-keyboard )。

我做了子类,但它不工作。

#import <UIKit/UIKit.h>


@protocol MyUITableViewDelegate <NSObject>
@optional
- (void)myUITableViewTouchesBegan;
@end


@interface MyUITableView : UITableView <UITableViewDelegate, UIScrollViewDelegate> {
id<MyUITableViewDelegate> delegate;
}
@end

。 m 文件

#import "MyUITableView.h"


@implementation MyUITableView


- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
NSLog(@"delegate scrollView"); //this is dont'work
[super scrollViewDidScroll:scrollView];
}


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(@"delegate myUITableViewTouchesBegan"); // work only here
[delegate myUITableViewTouchesBegan];
[super touchesBegan:touches withEvent:event];


}


- (void)dealloc {
...

我像这样使用这个类,但是委托函数 myUITableViewTouchesBegan 在 ViewController 中不起作用

。 h

#import <UIKit/UIKit.h>
#import "MyUITableView.h"


@interface FirstViewController : UIViewController <UITableViewDelegate, UISearchBarDelegate, MyUITableViewDelegate> {
MyUITableView *myTableView;
UISearchBar *searchBar;
}


@property(nonatomic,retain) IBOutlet MyUITableView *myTableView;
...

。 m

- (void) myUITableViewTouchesBegan{
NSLog(@"myUITableViewTouchesBegan");
[searchBar resignFirstResponder];
}

我在这个实现中遇到了一些问题:
1) myUITableViewTouchesBegn don’t work in ViewController
2)来自 MyUITableView.m-NSLog (@“ committee myUITableViewTouchesBegan”) ;的 NSLog 只有当我触摸桌面时才能工作。当我开始滚动时,它是如何工作的?
我试着覆盖 scrollViewDidScroll,但是 comiler 说 MyUITableView 可能不会响应这个字符串 < i > [ super scrollViewDidScroll: scrollView ] ;

73045 次浏览

不确定为什么需要为此子类化 UITableView。

在包含普通 UITableView 的视图控制器中,尝试添加以下内容:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
[searchBar resignFirstResponder];
}

以下是在 iOS 7.0及以上版本中实现这一点的最干净的方法:

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;

或在触摸时交互式地解雇:

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;

或者用斯威夫特的话说:

tableView.keyboardDismissMode = .onDrag

交互式地解散:

tableView.keyboardDismissMode = .interactive

你可以用 Interface Builder 做到的。选择 UITableView并打开属性检查器。在 Scroll View 部分中,将 键盘字段设置为 解散阻力

enter image description here

只是添加一个更新以上的答案。下面的工作为我在 Swift 1.2

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.OnDrag

或者

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.Interactive

不需要在 Controller 中编写单行代码的工作解决方案:

因为你的问题是处理隐藏键盘只有一个条件(滚动)。 但在这里,我推荐一种解决方案,以处理文本字段和键盘一起工作,像魅力的 UIViewController,UITableView 和 UIScrollView。有趣的是,您不需要编写任何一行代码。

给你 避免 TPKeyboard-一个可怕的解决方案,处理键盘和滚动

任务

在 Swift 3中滚动 UITableView 时以编程方式隐藏键盘

细节

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

故事板

<?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>

结果

enter image description here

在 iOS7之后,您可以简单地使用 tableview 属性

Swift 3.0 +

myTableView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.OnDrag

目标 C

myTableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;

对于早期版本,可以实现滚动视图委托。

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

和 Swift 5一起

为了在滚动 TableView 时隐藏键盘并停止正确的编辑,我们仍然需要 合并两种类型的答案:

  1. 例如,在 IB (如 凯尔所解释的)或 ViewDidLoad()代码(如 佩佩所解释的)中设置键盘解除模式:
tableView.keyboardDismissMode = .onDrag
  1. 强制当前文本字段辞职为第一响应者(如在 瓦西里的回答)。我们只需要将以下内容添加到 UITableViewController类中
    override func scrollViewDidScroll(_ scrollView: UIScrollView) {
if !tableView.isDecelerating {
view.endEditing(true)
}
}