ios 滚动 UITableView 时隐藏键盘

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4399357/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 18:15:59  来源:igfitidea点击:

Hide keyboard when scroll UITableView

iosuitableviewkeyboardscroll

提问by olegi

In my app i want hide keyboard when i start scrolling UITableView. I search about this in internet, and most answer is subclassing UITableView (http://stackoverflow.com/questions/3499810/tapping-a-uiscrollview-to-hide-the-keyboard).

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

I made subclass but it's dont work.

我做了子类,但它不起作用。

#import <UIKit/UIKit.h>

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

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

.m file

.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 {
...

I use this class like this. But delegate function myUITableViewTouchesBegan don't work in ViewController

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

.h

。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

.m

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

I have some troubles with this implemenation:
1) myUITableViewTouchesBegan dont work in ViewController
2) NSLog from MyUITableView.m - NSLog(@"delegate myUITableViewTouchesBegan");work only when i touch table. How made it's work also when i start scrolling?
I try override scrollViewDidScroll but comiler said that MyUITableVIew may be don't respond on this string [super scrollViewDidScroll:scrollView];

我在这个实现中遇到了一些麻烦:
1)myUITableViewTouchesBegan 在 ViewController 中不起作用
2)来自 MyUITableView.m 的NSLog- NSLog(@"delegate myUITableViewTouchesBegan"); 只有当我触摸桌子时才工作。当我开始滚动时,它是如何工作的?
我尝试覆盖 scrollViewDidScroll 但编译器说 MyUITableVIew 可能不响应此字符串[super scrollViewDidScroll:scrollView];

回答by Pei

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

这是在 iOS 7.0 及更高版本中实现此目标的最简洁方法:

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;

Or to dismiss interactively when touching:

或者在触摸时以交互方式关闭:

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;

Or in Swift:

或者在 Swift 中:

tableView.keyboardDismissMode = .onDrag

To dismiss interactively:

以交互方式关闭:

tableView.keyboardDismissMode = .interactive

回答by Pei

Not sure why you need to subclass UITableView for this.

不知道为什么您需要为此继承 UITableView 子类。

In the view controller that contains the plain UITableView, try adding this:

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

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

回答by Kyle Clegg

You can do this right in Interface Builder. Select your UITableViewand open the Attributes Inspector. In the Scroll View section set the Keyboardfield to Dismiss on Drag.

您可以直接在 Interface Builder 中执行此操作。选择您的UITableView并打开属性检查器。在 Scroll View 部分,将Keyboard字段设置为Dismiss on Drag

enter image description here

在此处输入图片说明

回答by Gareth Jones

Just to add an update to the answers above. The below worked for me in Swift 1.2

只是为上述答案添加更新。以下在 Swift 1.2 中对我有用

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.OnDrag

or

或者

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.Interactive

回答by Thierry G.

With Swift 5

使用 Swift 5

To hide the keyboard when scrolling the TableView and stop editing properly, we still need to combinetwo types of answers:

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

  1. Set the keyboard dismiss mode in IB (as Kyleexplained) or in ViewDidLoad()code (as Peiexplained) for instance:
  1. 例如,在 IB(如Kyle解释)或ViewDidLoad()代码(如Pei解释)中设置键盘关闭模式:
tableView.keyboardDismissMode = .onDrag
  1. Force the current textfield to resign as first responder (as in Vasily's answer). We just need to add the following to our UITableViewControllerclass
  1. 强制当前文本字段作为第一响应者辞职(如Vasily的回答)。我们只需要在我们的UITableViewController类中添加以下内容
    override func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if !tableView.isDecelerating {
            view.endEditing(true)
        }
    }

回答by iDevAmit

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.

因为您的问题是仅在一个条件下(滚动时)处理隐藏键盘。但在这里我推荐一种解决方案来一起处理文本字段和键盘,它就像 UIViewController、UITableView 和 UIScrollView 的魅力一样。有趣的事实是,您不需要编写任何一行代码。

Here you go: TPKeyboardAvoiding - An awesome solution to handle keyboard and scroll

给你:TPKeyboardAvoiding - 处理键盘和滚动的一个很棒的解决方案

回答by Vasily Bodnarchuk

Task

任务

Hide keyboard programmatically when scroll UITableView in Swift 3

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

Details

细节

xCode 8.2.1, swift 3

xCode 8.2.1,快速 3

Solution

解决方案

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    if !tableView.isDecelerating {
        view.endEditing(true)
    }
}

Full Sample

完整样本

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>

Result

结果

enter image description here

在此处输入图片说明

回答by varunrathi28

After iOS 7, you can simple use the tableview property

在 iOS 7 之后,你可以简单地使用 tableview 属性

Swift 3.0+

斯威夫特 3.0+

myTableView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.OnDrag

ObjectiveC

目标C

myTableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;

For earlier versions, implementing the scroll view delegate could work.

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

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