Sembunyikan keyboard saat menggulir UITableView

138

Di aplikasi saya, saya ingin menyembunyikan keyboard ketika saya mulai menggulir UITableView. Saya mencari tentang ini di internet, dan sebagian besar jawabannya adalah subclass UITableView (http://stackoverflow.com/questions/3499810/tapping-a-uiscrollview-to-hide-the-keyboard).

Saya membuat subclass tetapi tidak berhasil.

#import <UIKit/UIKit.h>

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

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

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

Saya menggunakan kelas ini seperti ini. Tetapi fungsi delegasi myUITableViewTouchesBegan tidak berfungsi di 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];
}

Saya memiliki beberapa masalah dengan penerapan ini:
1) myUITableViewTouchesBegan tidak berfungsi di ViewController
2) NSLog dari MyUITableView.m - NSLog (@ "delegate myUITableViewTouchesBegan"); bekerja hanya ketika saya menyentuh meja. Bagaimana membuatnya bekerja juga saat saya mulai menggulir?
Saya mencoba menimpa scrollViewDidScroll tetapi comiler mengatakan bahwa MyUITableVIew mungkin tidak merespons pada string ini [super scrollViewDidScroll: scrollView];

olegi
sumber

Jawaban:

148

Tidak yakin mengapa Anda perlu membuat subkelas UITableView untuk ini.

Di pengontrol tampilan yang berisi UITableView biasa, coba tambahkan ini:

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

sumber
422

Berikut adalah cara terbersih untuk mencapai ini di iOS 7.0 dan yang lebih baru:

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;

Atau untuk menutup secara interaktif saat menyentuh:

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;

Atau di Swift:

tableView.keyboardDismissMode = .onDrag

Untuk menutup secara interaktif:

tableView.keyboardDismissMode = .interactive
Pei
sumber
21
Atribut ini tentunya juga dapat disetel di pemeriksa atribut bagi mereka yang menggunakan ujung pena dan papan cerita.
JuJoDi
1
Sobat, saya benar-benar melewatkan ini sebagai pembaruan, saya masih menggunakan cara kuno dengan protokol yang scrollview menggulir .... Terima kasih sobat!
Tomas Sykora
3
Bagi yang lupa, Anda masih perlu membuat UITextfield resign first responder.
skyline75489
1
Saya telah melakukan pengembangan iOS sejak selama 3 tahun dan saya tidak tahu tentang ini sampai sekarang ... tidak nyata.
Jacob King
Bagaimana saya merindukan hal ini, brilian!
penjebak
130

Anda dapat melakukannya dengan benar di Interface Builder. Pilih Anda UITableViewdan buka Attributes Inspector. Di bagian Scroll View, setel bidang Keyboard ke Dismiss on Drag .

masukkan deskripsi gambar di sini

Kyle Clegg
sumber
Terima kasih kamu baru saja menyelamatkan hidupku!
Sabobin
41

Hanya untuk menambahkan pembaruan pada jawaban di atas. Di bawah ini berfungsi untuk saya di Swift 1.2

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.OnDrag

atau

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.Interactive
Gareth Jones
sumber
2

Dengan Swift 5

Untuk menyembunyikan keyboard saat menggulir TableView dan berhenti mengedit dengan benar, kita masih perlu menggabungkan dua jenis jawaban:

  1. Atur mode penutupan keyboard di IB (seperti yang dijelaskan Kyle ) atau dalam ViewDidLoad()kode (seperti yang dijelaskan Pei ) misalnya:
tableView.keyboardDismissMode = .onDrag
  1. Paksa bidang teks saat ini untuk mengundurkan diri sebagai responden pertama (seperti dalam jawaban Vasily ). Kami hanya perlu menambahkan yang berikut ini ke UITableViewControllerkelas kami
    override func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if !tableView.isDecelerating {
            view.endEditing(true)
        }
    }
Thierry G.
sumber
1

Solusi yang berfungsi tanpa menulis satu baris kode pun di Pengontrol Anda:

Seperti pertanyaan Anda adalah menangani keyboard hide dengan satu syarat saja (pada scroll). Tetapi di sini saya merekomendasikan satu solusi untuk menangani bidang teks dan keyboard bersama-sama yang berfungsi seperti pesona untuk UIViewController, UITableView dan UIScrollView. Fakta menariknya adalah Anda tidak perlu menulis satu baris kode pun.

Ini dia: TPKeyboardAvoiding - Solusi luar biasa untuk menangani keyboard dan scroll

iDevAmit
sumber
0

Tugas

Sembunyikan keyboard secara terprogram saat menggulir UITableView di Swift 3

Detail

xCode 8.2.1, cepat 3

Larutan

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

Sampel Lengkap

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>

Hasil

masukkan deskripsi gambar di sini

Bodnarchuk dengan mudah
sumber
0

Setelah iOS 7, Anda dapat menggunakan properti tableview dengan mudah

Swift 3.0+

myTableView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.OnDrag

TujuanC

myTableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;

Untuk versi yang lebih lama, menerapkan delegasi tampilan gulir dapat berfungsi.

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