Zastanawiam się, jak sprawić, aby klawiatura zniknęła, gdy użytkownik dotknie poza UITextField
.
Zastanawiam się, jak sprawić, aby klawiatura zniknęła, gdy użytkownik dotknie poza UITextField
.
Odpowiedzi:
Musisz dodać UITapGestureRecogniser
i przypisać go do widoku, a następnie wywołać rezygnację jako pierwsza osoba odpowiadająca na UITextField
selektorze.
Kod:
In viewDidLoad
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
Odrzuć klawiaturę:
-(void)dismissKeyboard
{
[aTextField resignFirstResponder];
}
(Gdzie aTextField
jest pole tekstowe odpowiedzialne za klawiaturę)
Tak wygląda wersja Swift 3
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.dismissKeyboard (_:)))
self.view.addGestureRecognizer(tapGesture)
Aby zamknąć klawiaturę
func dismissKeyboard (_ sender: UITapGestureRecognizer) {
aTextField.resignFirstResponder()
}
[aTextField resignFirstResponder]
by [self.view endEditing:YES];
to nie wymagało odniesienia do pola tekstowego i będzie działać na wielu polach tekstowych
[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self.view action:@selector(endEditing:)]];
[tap setCancelsTouchesInView:NO];
na odpowiedź @qiaoyi; Miałem problem z tabelą, która nie reagowała na wybrane wiersze. 5 lat później mam nadzieję, że pomoże to komuś innemu.
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:))))
Zebrałem kilka odpowiedzi.
Użyj ivara, który zostanie zainicjowany podczas viewDidLoad:
UIGestureRecognizer *tapper;
- (void)viewDidLoad
{
[super viewDidLoad];
tapper = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(handleSingleTap:)];
tapper.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:tapper];
}
Odrzuć to, co jest obecnie edytowane:
- (void)handleSingleTap:(UITapGestureRecognizer *) sender
{
[self.view endEditing:YES];
}
Sprawdź to, to byłby najłatwiejszy sposób, aby to zrobić,
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self.view endEditing:YES];// this will do the trick
}
Lub
Ta biblioteka będzie obsługiwać automatyczne przewijanie paska przewijania, dotknij spacji, aby ukryć klawiaturę itp.
Widzę, że niektórzy ludzie mają problemy z użyciem tej UITapGestureRecognizer
metody. Najłatwiejszym sposobem, w jaki osiągnąłem tę funkcjonalność, pozostawiając nienaruszone zachowanie mojego przycisku w stanie nienaruszonym, jest dodanie tylko jednej linii do odpowiedzi @ Jensen2k:
[tap setCancelsTouchesInView:NO];
Dzięki temu moje istniejące przyciski nadal działały bez użycia metody @Dmitry Sitnikov.
Przeczytaj o tym property
tutaj (szukaj CancelsTouchesInView
): Odwołanie do klasy UIGestureRecognizer
Nie jestem pewien, jak to będzie działać z paskami przewijania, ponieważ widzę, że niektórzy mieli problemy, ale mam nadzieję, że ktoś inny może spotkać się z tym samym scenariuszem, co ja.
UIImageView
, dodaj, [imageView setUserInteractionEnabled:NO];
a ty „klikniesz” go, co sprawia, że ta metoda działa.
Lepiej jest utworzyć UIView
instancję UIControl
(w programie do tworzenia interfejsów), a następnie połączyć ich TouchUpInside
zdarzenie z dismissKeyboard
metodą. Ta IBAction
metoda będzie wyglądać następująco:
- (IBAction)dismissKeyboard:(id)sender {
[aTextBox resignFirstResponder];
}
UITapGestureRecognizer
przeszkadzało to w naciskaniu przycisków w widoku). touchesEnded
nie działał, ponieważ wystąpił UIScrollView
Szybki 4
Skonfiguruj UIViewController
tę metodę rozszerzenia raz, np. W viewDidLoad
:
override func viewDidLoad() {
super.viewDidLoad()
self.setupHideKeyboardOnTap()
}
a klawiatura zostanie zwolniona nawet po dotknięciu przycisku NavigationBar
.
import UIKit
extension UIViewController {
/// Call this once to dismiss open keyboards by tapping anywhere in the view controller
func setupHideKeyboardOnTap() {
self.view.addGestureRecognizer(self.endEditingRecognizer())
self.navigationController?.navigationBar.addGestureRecognizer(self.endEditingRecognizer())
}
/// Dismisses the keyboard from self.view
private func endEditingRecognizer() -> UIGestureRecognizer {
let tap = UITapGestureRecognizer(target: self.view, action: #selector(self.view.endEditing(_:)))
tap.cancelsTouchesInView = false
return tap
}
}
Wersja szybka, działa w połączeniu z innymi elementami (takimi jak UIButton
inne UITextField
):
override func viewDidLoad() {
super.viewDidLoad()
let tapper = UITapGestureRecognizer(target: self, action:#selector(endEditing))
tapper.cancelsTouchesInView = false
view.addGestureRecognizer(tapper)
}
self
zamiastself.view
canclesTouchesInView
to przydatna właściwość do użycia. Dzięki.
c#
. Do Twojej wiadomości: Średnik jest dozwolony pod względem składni, po prostu nie jest konieczny.
Co powiesz na to: wiem, że to stary post. Może komuś pomóc :)
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
NSArray *subviews = [self.view subviews];
for (id objects in subviews) {
if ([objects isKindOfClass:[UITextField class]]) {
UITextField *theTextField = objects;
if ([objects isFirstResponder]) {
[theTextField resignFirstResponder];
}
}
}
}
To dobre ogólne rozwiązanie:
Cel C:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}
Szybki:
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
self.view.endEditing(true)
}
W oparciu o rozwiązanie @icodebuster: https://stackoverflow.com/a/18756253/417652
Swift 4 oneliner
view.addGestureRecognizer(UITapGestureRecognizer(target: view, action: #selector(UIView.endEditing(_:))))
Myślę, że najłatwiejszym (i najlepszym) sposobem na zrobienie tego jest podklasowanie globalnego widoku i użycie hitTest:withEvent
metody słuchania dowolnego dotyku. Dotyki na klawiaturze nie są rejestrowane, więc hitTest: withEvent jest wywoływany tylko po dotknięciu / przewinięciu / przesunięciu / ściśnięciu ... gdzie indziej, a następnie zadzwonić [self endEditing:YES]
.
Jest to lepsze niż używanie, touchesBegan
ponieważ touchesBegan
nie są wywoływane, jeśli klikniesz przycisk u góry widoku. Jest to lepsze niż, na przykład, UITapGestureRecognizer
który nie może rozpoznać gestu przewijania. Jest to również lepsze niż używanie przyciemnionego ekranu, ponieważ w złożonym i dynamicznym interfejsie użytkownika nie można wszędzie umieścić przyciemnionego ekranu. Co więcej, nie blokuje innych działań, nie musisz stuknąć dwa razy, aby wybrać przycisk na zewnątrz (jak w przypadku a UIPopover
).
Jest to także lepsze niż dzwonienie [textField resignFirstResponder]
, ponieważ na ekranie może znajdować się wiele pól tekstowych, więc działa to na wszystkie z nich.
To musi być najprostszy sposób na ukrycie klawiatury, dotykając jej na zewnątrz:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}
(z Jak odrzucić klawiaturę, gdy użytkownik stuknie inny obszar poza polem tekstowym? )
Jeśli widok jest w ogóle osadzony w UIScrollView
, możesz użyć następujących opcji:
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;
Pierwsza z nich będzie animować klawiaturę poza ekranem, gdy przewijany jest widok tabeli, a później ukryje klawiaturę, podobnie jak standardowa aplikacja Wiadomości.
Pamiętaj, że są one dostępne w systemie iOS 7.0 lub nowszym.
Możesz to zrobić za pomocą Storyboard w XCode 6 i nowszych:
Dodaj to do pliku nagłówka klasy używanej przez twój ViewController:
@interface TimeDelayViewController : UIViewController <UITextFieldDelegate>
- (IBAction)dissmissKeyboardOnTap:(id)sender;
@end
Następnie dodaj to do pliku implementacji tego samego ViewController:
- (IBAction)dissmissKeyboardOnTap:(id)sender{
[[self view]endEditing:YES];
}
Będzie to teraz jedna z „Otrzymanych akcji” dla sceny scenorysu (tj. ViewController):
Teraz musisz połączyć to działanie z gestem użytkownika polegającym na oderwaniu się od klawiatury.
Ważne - Musisz przekonwertować „UIView” zawarty w twojej serii ujęć na UIControl , aby mógł odbierać zdarzenia. Wybierz widok z hierarchii Scena kontrolera widoku:
... i zmień klasę:
Teraz przeciągnij z małego kółka obok „odebranej akcji” dla swojej sceny na „pustą” część sceny (w rzeczywistości przeciągasz „Otrzymaną akcję” do UIControl). Zobaczysz wybór wydarzeń, które możesz podłączyć do:
Wybierz opcję „retusz wewnątrz”. Teraz podłączyłeś utworzoną IBAction do akcji polegającej na dotykaniu klawiatury. Gdy użytkownik stuknie klawiaturę, teraz będzie ukryta.
(UWAGA: Aby dołączyć akcję do zdarzenia, możesz również przeciągnąć z odebranej akcji bezpośrednio do UIControl w hierarchii kontrolerów widoku. Jest ona wyświetlana jako „Kontrola” w hierarchii.)
Jeśli dobrze zrozumiałem, chcesz zrezygnować z dotykania klawiatury po zewnętrznej stronie, textfield
ale nie masz swojego odniesienia textfield
.
Spróbuj tego;
reftextField
Teraz w textFieldDidBeginEditing
ustawionym polu tekstowym odniesienia do
- (void) textFieldDidBeginEditing:(UITextField *)textField{
reftextField = textField;
}
Teraz możesz z radością korzystać z dowolnego przycisku zegara (zalecane dodanie przezroczystego przycisku przy rozpoczęciu edycji)
- (void)dismissKeyboard {
[reftextField resignFirstResponder];
}
Lub zrezygnuj z przycisku gotowe, spróbuj tego.
//for resigning on done button
- (BOOL) textFieldShouldReturn:(UITextField *)textField{
[textField resignFirstResponder];
return YES;
}
Wystarczy dodać do listy tutaj moją wersję, jak odrzucić klawiaturę na zewnątrz.
viewDidLoad:
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
[self.view addGestureRecognizer:singleTap];
Gdziekolwiek:
-(void)handleSingleTap:(UITapGestureRecognizer *)sender{
[textFieldName resignFirstResponder];
puts("Dismissed the keyboard");
}
Mnóstwo świetnych odpowiedzi na temat używania - UITapGestureRecognizer
w tym wszystkich UITextField
przycisków zerowania (X). Rozwiązaniem jest stłumienie rozpoznawania gestów za pośrednictwem jego delegata:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
BOOL touchViewIsButton = [touch.view isKindOfClass:[UIButton class]];
BOOL touchSuperviewIsTextField = [[touch.view superview] isKindOfClass:[UITextField class]];
return !(touchViewIsButton && touchSuperviewIsTextField);
}
To nie jest najbardziej niezawodne rozwiązanie, ale działa dla mnie.
return !touchViewIsButton
. Sądzę, że wszelkie inne przyciski, które muszą zwolnić klawiaturę, powinny to robić w swoich działaniach. Ponadto TouchUpInside może nie zostać wywołany, gdy zmieni się układ po zwolnieniu klawiatury.
Możesz utworzyć kategorię dla UiView i przesłonić szlak Rozpocznij meathod w następujący sposób.
Działa dla mnie dobrze i jest scentralizowanym rozwiązaniem tego problemu.
#import "UIView+Keyboard.h"
@implementation UIView(Keyboard)
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.window endEditing:true];
[super touchesBegan:touches withEvent:event];
}
@end
Szybka wersja odpowiedzi @ Jensen2k:
let gestureRecognizer : UITapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: "dismissKeyboard")
self.view.addGestureRecognizer(gestureRecognizer)
func dismissKeyboard() {
aTextField.resignFirstResponder()
}
Jedna wkładka
self.view.addTapGesture(UITapGestureRecognizer.init(target: self, action: "endEditing:"))
Użyłem przykładu Barry do mojego nowego projektu. Działa świetnie! ale musiałem wprowadzić niewielką zmianę, wymaganą do zwolnienia klawiatury tylko dla edytowanego pola tekstowego.
Dodałem więc do przykładu Barry:
- (void) textFieldDidBeginEditing:(UITextField *)textField
{
_textBeingEdited = textField;
}
-(void) textFieldDidEndEditing:(UITextField *)textField
{
_textBeingEdited = nil;
}
Zmieniłem również metodę hideKeyboard w następujący sposób:
- (IBAction)hideKeyboard:(id)sender
{
// Just call resignFirstResponder on all UITextFields and UITextViews in this VC
// Why? Because it works and checking which one was last active gets messy.
//UITextField * tf = (UITextField *) sender;
[_textBeingEdited resignFirstResponder];
}
Jednym z najłatwiejszych i najkrótszych sposobów jest dodanie tego kodu do swojego viewDidLoad
[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc]
initWithTarget:self.view
action:@selector(endEditing:)]];
Próbowałem tutaj wielu odpowiedzi i nie miałem szczęścia. Mój rozpoznawanie gestów dotknij zawsze powodowało, że UIButtons
nie reagowałem po stuknięciu, nawet gdy ustawiłem cancelsTouchesInView
właściwość rozpoznawania gestów na NIE.
Oto, co ostatecznie rozwiązało problem:
Mieć ivar:
UITapGestureRecognizer *_keyboardDismissGestureRecognizer;
Gdy pole tekstowe zacznie się edytować, ustaw rozpoznawanie gestów:
- (void) textFieldDidBeginEditing:(UITextField *)textField
{
if(_keyboardDismissGestureRecognizer == nil)
{
_keyboardDismissGestureRecognizer = [[[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(dismissKeyboard)] autorelease];
_keyboardDismissGestureRecognizer.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:_keyboardDismissGestureRecognizer];
}
}
Zatem sztuczka polega na tym, jak skonfigurować dismissKeyboard
metodę:
- (void) dismissKeyboard
{
[self performSelector:@selector(dismissKeyboardSelector) withObject:nil afterDelay:0.01];
}
- (void) dismissKeyboardSelector
{
[self.view endEditing:YES];
[self.view removeGestureRecognizer:_keyboardDismissGestureRecognizer];
_keyboardDismissGestureRecognizer = nil;
}
Wydaje mi się, że jest coś w dismissKeyboardSelector
wydobywaniu wykonania ze stosu wykonawczego obsługi dotykowej ...
Wyślij wiadomość resignFirstResponder
do pliku tekstowego, który ją tam umieścił. Więcej informacji można znaleźć w tym poście .
W tym przykładzie aTextField jest jedynym UITextField ... Jeśli są inne lub UITextViews, jest trochę więcej do zrobienia.
// YourViewController.h
// ...
@interface YourViewController : UIViewController /* some subclass of UIViewController */ <UITextFieldDelegate> // <-- add this protocol
// ...
@end
// YourViewController.m
@interface YourViewController ()
@property (nonatomic, strong, readonly) UITapGestureRecognizer *singleTapRecognizer;
@end
// ...
@implementation
@synthesize singleTapRecognizer = _singleTapRecognizer;
// ...
- (void)viewDidLoad
{
[super viewDidLoad];
// your other init code here
[self.view addGestureRecognizer:self.singleTapRecognizer];
{
- (UITapGestureRecognizer *)singleTapRecognizer
{
if (nil == _singleTapRecognizer) {
_singleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapToDismissKeyboard:)];
_singleTapRecognizer.cancelsTouchesInView = NO; // absolutely required, otherwise "tap" eats events.
}
return _singleTapRecognizer;
}
// Something inside this VC's view was tapped (except the navbar/toolbar)
- (void)singleTapToDismissKeyboard:(UITapGestureRecognizer *)sender
{
NSLog(@"singleTap");
[self hideKeyboard:sender];
}
// When the "Return" key is pressed on the on-screen keyboard, hide the keyboard.
// for protocol UITextFieldDelegate
- (BOOL)textFieldShouldReturn:(UITextField*)textField
{
NSLog(@"Return pressed");
[self hideKeyboard:textField];
return YES;
}
- (IBAction)hideKeyboard:(id)sender
{
// Just call resignFirstResponder on all UITextFields and UITextViews in this VC
// Why? Because it works and checking which one was last active gets messy.
[aTextField resignFirstResponder];
NSLog(@"keyboard hidden");
}
- (void)viewDidLoad
{
[super viewDidLoad];
UITapGestureRecognizer *singleTapGestureRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(handleSingleTap:)];
[singleTapGestureRecognizer setNumberOfTapsRequired:1];
[singleTapGestureRecognizer requireGestureRecognizerToFail:singleTapGestureRecognizer];
[self.view addGestureRecognizer:singleTapGestureRecognizer];
}
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer
{
[self.view endEditing:YES];
[textField resignFirstResponder];
[scrollView setContentOffset:CGPointMake(0, -40) animated:YES];
}
Dodaj ten kod do pliku ViewController.m :
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
}
W takim przypadku można użyć ScrollView i dodać do TextField
ScrollView i chcę Stuknij ScrollView
i Widok, a następnie Zamknij klawiaturę. Na wszelki wypadek próbowałem utworzyć przykładowy kod. Lubię to,
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.tap(_:)))
view.addGestureRecognizer(tapGesture)
// Do any additional setup after loading the view, typically from a nib.
}
func tap(gesture: UITapGestureRecognizer) {
textField.resignFirstResponder()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Twój Storyboard Spójrz na to tak jak.
Możesz użyć metody UITapGestureRecongnizer do odrzucenia klawiatury, klikając poza polem UITextField. Korzystając z tej metody, ilekroć użytkownik kliknie poza UITextField, klawiatura zostanie zwolniona. Poniżej znajduje się fragment kodu umożliwiający jego użycie.
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(dismissk)];
[self.view addGestureRecognizer:tap];
//Method
- (void) dismissk
{
[abctextfield resignFirstResponder];
[deftextfield resignFirstResponder];
}