Ocultar teclado al desplazarse UITableView

134

En mi aplicación, quiero ocultar el teclado cuando empiezo a desplazar UITableView. Busco sobre esto en Internet, y la mayoría de las respuestas son subclases UITableView (http://stackoverflow.com/questions/3499810/tapping-a-uiscrollview-to-hide-the-keyboard).

Hice una subclase pero no funciona.

#import <UIKit/UIKit.h>

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

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

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

Yo uso esta clase como esta. Pero la función delegar myUITableViewTouchesBegan no funciona en 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;
...

.metro

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

Tengo algunos problemas con esta implementación:
1) myUITableViewTouchesBegan no funciona en ViewController
2) NSLog de MyUITableView.m - NSLog (@ "delegar myUITableViewTouchesBegan"); funciona solo cuando toco la mesa. ¿Cómo funciona también cuando empiezo a desplazarme?
Intento anular scrollViewDidScroll pero el comiler dijo que MyUITableVIew puede no responder en esta cadena [super scrollViewDidScroll: scrollView];

olegi
fuente

Respuestas:

144

No estoy seguro de por qué necesita subclasificar UITableView para esto.

En el controlador de vista que contiene el UITableView simple, intente agregar esto:

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

fuente
418

Aquí está la forma más limpia de lograr esto en iOS 7.0 y superior:

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;

O descartar interactivamente al tocar:

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;

O en Swift:

tableView.keyboardDismissMode = .onDrag

Para descartar de forma interactiva:

tableView.keyboardDismissMode = .interactive
Pei
fuente
21
Por supuesto, este atributo también se puede establecer en el inspector de atributos para aquellos que usan plumillas y guiones gráficos.
JuJoDi
1
Amigo, enloquecí por completo, perdí esto como una actualización, todavía estaba usando la forma antigua con el protocolo que scrollview se desplazó ... ¡Gracias, amigo!
Tomás Sykora
3
Para aquellos que se olvidan, aún debe hacer que UITextfield renuncie al primer respondedor.
skyline75489
1
He estado haciendo desarrollo de iOS desde hace 3 años y no sabía sobre esto hasta ahora ... irreal.
Jacob King
¿Cómo extraño estas cosas, genial!
trampero
129

Puede hacerlo directamente en Interface Builder. Seleccione su UITableViewy abra el Inspector de atributos. En la sección Vista de desplazamiento, configure el campo Teclado en Descartar al arrastrar .

ingrese la descripción de la imagen aquí

Kyle Clegg
fuente
¡Gracias, me salvaste la vida!
Sabobin
41

Solo para agregar una actualización a las respuestas anteriores. Lo siguiente funcionó para mí en Swift 1.2

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.OnDrag

o

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.Interactive
Gareth Jones
fuente
2

Con Swift 5

Para ocultar el teclado al desplazarse por TableView y detener la edición correctamente, aún necesitamos combinar dos tipos de respuestas:

  1. Configure el modo de descarte del teclado en IB (como explicó Kyle ) o en ViewDidLoad()código (como explicó Pei ) por ejemplo:
tableView.keyboardDismissMode = .onDrag
  1. Forzar el campo de texto actual a renunciar como primer respondedor (como en la respuesta de Vasily ). Solo necesitamos agregar lo siguiente a nuestra UITableViewControllerclase
    override func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if !tableView.isDecelerating {
            view.endEditing(true)
        }
    }
Thierry G.
fuente
1

Solución de trabajo sin escribir una sola línea de código en su controlador:

Como su pregunta es manejar el teclado oculto con una sola condición (en desplazamiento). Pero aquí estoy recomendando una solución para manejar el campo de texto y el teclado juntos que funciona de maravilla para UIViewController, UITableView y UIScrollView. El hecho interesante es que no necesita escribir una sola línea de código.

Aquí tienes: TPKeyboardAvoiding: una solución increíble para manejar el teclado y el desplazamiento

iDevAmit
fuente
0

Tarea

Ocultar el teclado mediante programación cuando se desplaza UITableView en Swift 3

Detalles

xCode 8.2.1, swift 3

Solución

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

Muestra completa

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>

Resultado

ingrese la descripción de la imagen aquí

Vasily Bodnarchuk
fuente
0

Después de iOS 7, puedes usar la propiedad tableview

Swift 3.0+

myTableView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.OnDrag

C objetivo

myTableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;

Para versiones anteriores, la implementación del delegado de vista de desplazamiento podría funcionar.

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