简体   繁体   English

滚动UITableView时隐藏键盘

[英]Hide keyboard when scroll UITableView

In my app i want hide keyboard when i start scrolling UITableView. 在我的应用程序中,当我开始滚动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(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 1)myUITableViewTouchesBegan在ViewController中不起作用
2) NSLog from MyUITableView.m - NSLog(@"delegate myUITableViewTouchesBegan"); 2)来自MyUITableView.m的NSLog - 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]; 我尝试覆盖scrollViewDidScroll但是comiler说MyUITableVIew可能不响应这个字符串[super scrollViewDidScroll:scrollView];

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

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];
}

You can do this right in Interface Builder. 您可以在Interface Builder中执行此操作。 Select your UITableView and open the Attributes Inspector. 选择您的UITableView并打开Attributes Inspector。 In the Scroll View section set the Keyboard field to Dismiss on Drag . 在“滚动视图”部分中,将“ 键盘”字段设置为“拖动时关闭”

在此输入图像描述

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

Working solution without writing single line of code in your Controller: 无需在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. 但是在这里我推荐一种解决方案来处理文本字段和键盘,它们就像UIViewController,UITableView和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 在这里: TPKeyboardAvoiding - 处理键盘和滚动的一个很棒的解决方案

Task 任务

Hide keyboard programmatically when scroll UITableView in Swift 3 在Swift 3中滚动UITableView时以编程方式隐藏键盘

Details 细节

xCode 8.2.1, swift 3 xCode 8.2.1,swift 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 结果

在此输入图像描述

After iOS 7, you can simple use the tableview property 在iOS 7之后,您可以简单地使用tableview属性

Swift 3.0+ Swift 3.0+

myTableView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.OnDrag

ObjectiveC 的ObjectiveC

myTableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;

For earlier versions, implementing the scroll view delegate could work. 对于早期版本,实现滚动视图委托可以工作。

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

With Swift 5 使用Swift 5

To hide the keyboard when scrolling the TableView and stop editing properly, we still need to combine two types of answers: 要在滚动TableView时隐藏键盘并停止正确编辑,我们仍需要结合两种类型的答案:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM