Відхиліть клавіатуру, торкнувшись фону UITableView


105

У мене є UITableViewз UITextFieldз як клітини. Я б хотів відхилити клавіатуру, коли UITableViewторкається тла . Я намагаюся це зробити, створивши UIButtonрозмір UITableViewі розміщуючи його за межі UITableView. Єдина проблема полягає в UIButtonтому, щоб наздогнати всі дотики, навіть коли дотик знаходиться на UITableView. Що я роблю неправильно?

Дякую!


Питання та відповіді, що відхиляються: Q1 , Q2 , Q3 .
Yantao Xie

Це найкраща відповідь stackoverflow.com/a/12851794/1418457
onmyway133

Відповіді:


203

Це легко зробити, створивши UITapGestureRecognizer (за замовчуванням це буде виявляти "жест" одним натисканням, тому подальше налаштування не потрібно), вказуючи ціль / дію для того, коли жест запускається, а потім додаючи об'єкт розпізнавання жестів на подання таблиці.

Наприклад, у вашому viewDidLoadметоді:

UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
[self.tableView addGestureRecognizer:gestureRecognizer];

І hideKeyboardметод може виглядати приблизно так:

- (void) hideKeyboard {
    [textField1 resignFirstResponder];
    [textField2 resignFirstResponder];
    ...
    ...
}

Зауважте, що жест не спрацьовує під час торкання всередині UITextFieldпредмета. Він запускається, хоча на UITableViewтлі, подання нижнього колонтитула, вигляд заголовка та на UILabelsвнутрішні комірки тощо


4
Коли я спробував це, я виявив, що це заважає таблиці вибирати клітини :(. Дивовижний варіант в іншому випадку
Брайан

109
Як gestureRecognizer.cancelsTouchesInView = NO;
наголошене

3
І не забудьте випустити gestureRecognizer, як тільки він буде приєднаний до tableView.
Пол Лінч

39
Для hideKeyboardметоду замість спілкування безпосередньо з текстовими полями ви можете це зробити [self.view endEditing:NO];. Від документів Apple: " Цей метод розглядає поточний вигляд та його ієрархію підвідного перегляду для текстового поля, яке наразі є першим відповідачем. Якщо він знайде його, він просить це текстове поле подати у відставку як перший відповідь. Якщо для параметра параметра" сила "встановлено значення Так, текстове поле ніколи навіть не запитується; воно змушене піти у відставку ".
Гобот

1
таким чином мій метод "didSelectRowAtIndexPath" не викликає. будь-яке рішення для цього ??
uniruddh

127

Рішення UITapGestureRecognizer працює з вибором комірок таблиці, якщо встановити:

gestureRecognizer.cancelsTouchesInView = NO;

1
Це дозволяє торкнутися клітинки, але жест також розпізнається, можливо, ми повинні реалізувати цей метод делегуванняshouldReceiveTouch
onmyway133

61

Ось найкращий спосіб зробити це. Просто роби це

[self.view endEditing:YES];

або

[[self.tableView superView] endEditing:YES];

куди мені поставити цей код? вибачте, що я початківець. І, будь ласка, вкажіть швидкий код.
Джон

54

Ви також можете зробити це з «Розгортки»: введіть тут опис зображення


1
Що б я не вибрав: Відхилити при перетягуванні, Відхилити інтерактивно, коли я торкаюся комірки таблиці, вона вибирається. Я використовую Xcode 8, стрімкий 3. будь ласка, допоможіть
John

22

Як UITableViewі підклас UIScrollView, реалізація одного методу делегата нижче забезпечує надзвичайно просте, швидке рішення. Не потрібно навіть залучати, resignFirstResponderоскільки переглядає ієрархію самоаналізу та знаходить поточного респондента та просить його подати у відставку його статус відповіді.

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    [self.view endEditing:YES];
}

І не забудьте додати UIScrollViewDelegate до файлу заголовка.


2
Це можна зробити за допомогою цього вкладиша, як вказував @Joe Masilotti, якщо ви орієнтуєтесь на iOS7 і вище: self.tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
atulkhatri

Що станеться, якщо натиснути на текстове поле в нижній частині екрана, яке повинно прокручуватися вгору, щоб показати клавіатуру? - Ваша клавіатура буде прихована.
Іслам Q.

Swift 4 - self.tableView.keyboardDismissMode = UIScrollViewKeyboardDismissMode.onDrag
RobLabs

13

По-перше, послухайте scrollViewWillBeginDraggingу своєму UIViewController, додавшиUIScrollViewDelegate :

У .h файлі:

@interface MyViewController : UIViewController <UIScrollViewDelegate> 

У файлі .m:

- (void)scrollViewWillBeginDragging:(UIScrollView *)activeScrollView {

    [self dismissKeyboard];

}

Потім слухайте інші взаємодії:

- (void)setupKeyboardDismissTaps {

    UISwipeGestureRecognizer *swipeUpGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    swipeUpGestureRecognizer.cancelsTouchesInView = NO;
    swipeUpGestureRecognizer.direction = UISwipeGestureRecognizerDirectionUp;
    [self.tableView addGestureRecognizer:swipeUpGestureRecognizer];

    UISwipeGestureRecognizer *swipeDownGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    swipeDownGestureRecognizer.cancelsTouchesInView = NO;
    swipeDownGestureRecognizer.direction = UISwipeGestureRecognizerDirectionDown;
    [self.tableView addGestureRecognizer:swipeDownGestureRecognizer];

    UISwipeGestureRecognizer *swipeLeftGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    swipeLeftGestureRecognizer.cancelsTouchesInView = NO;
    swipeLeftGestureRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
    [self.tableView addGestureRecognizer:swipeLeftGestureRecognizer];

    UISwipeGestureRecognizer *swipeRightGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    swipeRightGestureRecognizer.cancelsTouchesInView = NO;
    swipeRightGestureRecognizer.direction = UISwipeGestureRecognizerDirectionRight;
    [self.tableView addGestureRecognizer:swipeRightGestureRecognizer];


    UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
    tapGestureRecognizer.cancelsTouchesInView = NO;
    [self.tableView addGestureRecognizer:tapGestureRecognizer];

}

Потім реалізуйте dismissKeyboard:

- (void)dismissKeyboard {

    NSLog(@"dismissKeyboard");

    [yourTextFieldPointer resignFirstResponder];

}

І якщо ви, як я, хотіли відхилити клавіатуру для UITextField усередині спеціальної комірки таблиці:

- (void)dismissKeyboard {

    NSLog(@"dismissKeyboard");

    CustomCellClass *customCell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
    [customCell.textFieldInCell resignFirstResponder]; 

}

Сподіваюся, що допоможе хто шукає !!



8

Ось швидка версія вашого задоволення від кодування:

Він додає розпізнавальний жест натискання, а потім відхиляє клавіатуру. Жодна розетка для TextField не потрібна!

override func viewDidLoad() {
    super.viewDidLoad()
    view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "handleTap:"))
}

func handleTap(sender: UITapGestureRecognizer) {
    if sender.state == .Ended {
        view.endEditing(true)
    }
    sender.cancelsTouchesInView = false
}

1
Це працює навіть із власною таблицеюViewCell! Я витратив стільки часу, намагаючись зрозуміти це. Дуже дякую! Ви - мій герой. youtu.be/EqWRaAF6_WY
миролюбний

8

Існує версія Swift 3 без блокування натискань на комірки.

У viewDidLoad()способі:

let dismissKeyboardGesture = UITapGestureRecognizer(target: self, action: #selector(hideKeyboard))
dismissKeyboardGesture.cancelsTouchesInView = false
tableView.addGestureRecognizer(dismissKeyboardGesture)

І hideKeyboardвиглядає так:

func hideKeyboard() {
    view.endEditing(true)
}

7

Я зробив це так:

Створіть у своєму TableViewController метод для дезактивації першого відповіді (який би був вашим TextBox в цей момент)

- (BOOL)findAndResignFirstResonder:(UIView *)stView {
    if (stView.isFirstResponder) {
        [stView resignFirstResponder];
        return YES;     
    }

    for (UIView *subView in stView.subviews) {
        if ([self findAndResignFirstResonder:subView]) {
            return YES;
        }
    }
    return NO;
}

У tableView:didSelectRowAtIndexPath:виклику попередній метод:

- (void)tableView:(UITableView *)tableView
                             didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    ...
    [self findAndResignFirstResonder: self.view];
    ...
}

ви робите це неправильно так, як просите. ви не кладете кнопку на подання, ви кажете погляду видалити клавіатуру, як сказано у цій відповіді

2
Це прекрасно працює, якщо ви натискаєте всередині комірки подання таблиці (і поза будь-якого UITextField у межах цієї комірки подання таблиці). Однак, якщо я торкнуся фону подання таблиці (що найчастіше є легшою ціллю для досягнення - закон закону Фіттса!), Такої удачі немає. Правда, це і очікується, оскільки ми виконуємо цю операцію в tableView: didSelectRowAtIndexPath :. Якщо це можна якось відрегулювати для роботи з натисканням на будь-яке інше місце у поданні таблиці (це інакше не хотілося б фокусування на клавіатурі), я думаю, у нас тут переможець!
Джо Д'Андреа

У мене така ж проблема, як і jdandrea. Це didSelectRowAtIndexPathне спрацьовує, якщо натиснути сам TableView.
zekel

якщо didSelectRowAtIndexPath недостатньо, зробіть те ж саме і в tougsBegan!
Амо Талпалікар

5

У мене був UITableViewControllerі реалізаціяtouchesBegan:withEvent: не працювало для мене.

Ось що працювало:

Швидкий:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    view.endEditing(true)
}

Завдання-C:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [self.view endEditing:YES];
}

Гарна ідея, мені це подобається.
HotFudgeSunday

4
@interface DismissableUITableView : UITableView {
}
@end

@implementation DismissableUITableView

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
 [self.superview endEditing:YES];
 [super touchesBegan:touches withEvent:event];
}

@end

Потім переконайтесь, що у вашому файлі Nib ви встановите тип вашого UITableView на DismissableUITableView ..... можливо, я міг би придумати кращу назву для цього класу, але ви отримаєте бал.


4

Якщо ви орієнтуєтесь на iOS7, ви можете скористатись одним із наступних дій:

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;

Перший буде анімувати екран клавіатури, коли прокручується подання таблиці, а пізніше приховає клавіатуру, як додаток Повідомлення про запас.

Зауважте, що це від UIScrollView, від яких UITableViewуспадковується.


приємно. Мені вдається розірвати його, просуваючи вгору по екрану вгору, поки клавіатура не почала рухатися вниз, потім перетягувати назад, поки клавіатура трохи не рухалася вгору, а потім відпускала. огляд прокрутки не повертається до вершини як слід.
Сем

3

Спробуйте це:

viewDidLoad(){

    let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))

    tableView.addGestureRecognizer(tap)

}
//Calls this function when the tap is recognized.
@objc func dismissKeyboard() {

    //Causes the view (or one of its embedded text fields) to resign the first responder status.
    view.endEditing(true)

}

2

UITableView - підклас UIScrollView.

Я зробив це, щоб прослухати подія прокрутки користувачем, а потім подати у відставкуFirstResponder. Ось метод UIScrollViewDelegate для впровадження у свій код;

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView

Підходячи до подібних завдань, я знайшов найкращий спосіб - дослідити протоколи делегації для кожного об'єкта та батьківських класів (у цьому випадку UITableViewDelegate, UIScrollViewDelegate. Кількість подій, що виникають в NS-об'єктах, досить велика та всебічна. Це також простіше реалізувати протокол, а потім підкласифікувати що-небудь.


2

У мене була така ж проблема, і ось моє рішення, воно прекрасно працює для мене:

У контролері подання чи перегляду, який ви реалізували <UITextFieldDelegate>

(У моєму випадку у мене є звичай UITableViewCell під назвою TextFieldCell),

Заявіть UITapGestureRecognizerяк власність:

@interface TextFieldCell : UITableViewCell <UITextFieldDelegate>
{
    UITextField *theTextField;
    UITapGestureRecognizer *gestureRecognizer;
}
@property (nonatomic,retain) UITextField *theTextField;
@property (nonatomic,retain) UITapGestureRecognizer *gestureRecognizer; 

І ініціалізуйте його у вашому перегляді / контролері:

self.gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(closeKeyboard:)];

У цьому - (void)textFieldDidBeginEditing:(UITextField *)textFieldспособі використовуйте superViewдля переходу до таблиціView та виклику addGestureRecognizer:

[self.superview.superview addGestureRecognizer:gestureRecognizer];

І в - (void)textFieldDidEndEditing:(UITextField *)textField, просто видаліть розпізнавальник жестів:

[self.superview.superview removeGestureRecognizer:gestureRecognizer];

Сподіваюся, це допомагає.


Це зробило це для мене. Спасибі hac.jack
gilsaints88

2

Я хотів, щоб моя клітинка відкрила клавіатуру, коли була вибрана будь-яка частина комірки, і закрити її, якщо ви клацнули де-небудь із клітинки. Щоб відкрити клавіатуру:

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];
    if (selected)
    {
        [self.textField becomeFirstResponder];
    }
}

(ПРИМІТКА. Я підкласив клітинку, але ви можете легко досягти цього tableView:didSelectRowAtIndexPath:методом делегуванняUITableView )

Це означало, що при найпопулярніших рішеннях, якщо двічі натиснути на клітинку, клавіатура похитнеться, по-перше, розпізнавач жестів спробував закрити клавіатуру, а по-друге, клітинку було обрано повторно та спробувало відкрити клавіатуру.

Рішення полягає в тому, щоб перевірити, чи відбулося натискання всередині вибраної комірки:

- (void)viewDidLoad
{
    [super viewDidLoad];
    //gesture recognizer to close the keyboard when user taps away
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                          action:@selector(dismissKeyboard:)];
    tap.cancelsTouchesInView = NO;
    [self.tableView addGestureRecognizer:tap];
}

-(void)dismissKeyboard:(UIGestureRecognizer*)tapGestureRecognizer
{
    if (!CGRectContainsPoint([self.tableView cellForRowAtIndexPath:[self.tableView indexPathForSelectedRow]].frame, [tapGestureRecognizer locationInView:self.tableView]))
    {
        [self.view endEditing:YES];
    }
}

2

Я знайшов рішення, яке чудово працює.

Потрібно використовувати UIGestureRecognizerDelegate і метод - gestureRecognizer: shouldReceiveTouch: .

Додайте розпізнавальник жестів до TableView таким чином:

UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
tapGestureRecognizer.cancelsTouchesInView = NO;
tapGestureRecognizer.delegate = self;
[self.suggestedTableView addGestureRecognizer:tapGestureRecognizer];
[tapGestureRecognizer release];

Потім застосуйте метод делегата слідReceiveTouch, щоб відхилити дотики, які виконуються в класі UITableViewCell. Метод hidKeyboard буде викликаний лише тоді, коли дотик виконано поза класом UITableViewCell.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    if([touch.view isKindOfClass:[UITableViewCell class]]) {
        return NO;
    }
    // UITableViewCellContentView => UITableViewCell
    if([touch.view.superview isKindOfClass:[UITableViewCell class]]) {
        return NO;
    }
    // UITableViewCellContentView => UITableViewCellScrollView => UITableViewCell
    if([touch.view.superview.superview isKindOfClass:[UITableViewCell class]]) {
        return NO;
    }
    return YES; // handle the touch
}

- (void) hideKeyboard{
    [textField resignFirstResponder];
}

2

UITableViewмає зручну backgroundViewвластивість, з якою я домігся такої поведінки, не возившись з вибором комірок, як показано нижче у Swift:

let tableBackTapRecognizer = UITapGestureRecognizer(target: self, action: #selector(hideKeyboard))
tableView.backgroundView = UIView()
tableView.backgroundView?.addGestureRecognizer(tableBackTapRecognizer)

1

Я шукав рішення і не знайшов нічого, що могло б відповідати моєму коду, тому я зробив це так:

http://82517.tumblr.com/post/13189719252/dismiss-keyboard-on-uitableview-non-cell-tap

Це, в основному, комбінація раніше згаданих підходів, але не вимагає нічого підкласу або створення фонових кнопок.


1

Просто використання UITapGestureRecognizer і cancelsTouchesInView = NOозначає, що натискання на комірки та UITextViews також викликає приховування. Це погано, якщо у вас є кілька UITextView, і ви натискаєте наступний. Клавіатура почне приховувати, а потім наступний textView стане першим Відповідачем, і клавіатура знову стане видимою. Щоб уникнути цього, перевірте розташування крана та прихойте клавіатуру лише у випадку, якщо крана немає на комірці:

// init
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapTableView:)];
tapRecognizer.cancelsTouchesInView = NO;
[self.tableView addGestureRecognizer:tapRecognizer];


// Hide on tap
- (void)didTapTableView:(UITapGestureRecognizer *)tap
{
    CGPoint point = [tap locationInView:tap.view];
    [self.view endEditing:!CGRectContainsPoint([self.tableView rectForRowAtIndexPath:[self.tableView indexPathForRowAtPoint:point]], point)];
}

Для того, scrollViewWillBeginDragging:щоб його запустили, scrollEnabledмає бути властивість tableViewYES

// Hide on scroll
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    [self.view endEditing:YES];
}

Ідеально підходить для мене. До комірки перегляду таблиць додано текстове поле; якщо я торкнуся за межами клавіатури відхилити
Nicola

0

Чому ви хочете створити таблицю з текстовими полями? Ви повинні використовувати докладний вигляд для кожного рядка, який містить текстові поля. Коли ви натискаєте детальний перегляд, переконайтесь, що ви викликаєте "[myTextField postalaFirstResponder]", щоб користувач міг розпочати редагування лише одним клацанням миші від списку таблиць.


Додаток Apple-контакти Контакти робить саме це. Я б не сказав, що воно повна текстових полів, але воно використовує їх для хорошого ефекту.
Джо Д'Андреа

2
Редагування вбудованого тексту в режимі перегляду таблиці набагато швидше та інтуїтивніше, ніж натискання детальних переглядів для кожного текстового поля, який користувач хоче редагувати ... просто запитайте найближчу форму HTML або текстові поля на панелях налаштувань iPhone, або в програмі "Контакти", або і т. д. і т. д. і т. д. ... це справді шкода, що Apple не зробила це типовим типом комірок, але в Інтернеті є багато інформації про досягнення цього.
glenc

0

Якщо ви готові підклас (ух!) Свій перегляд таблиці, щось подібне може спрацювати:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

   BOOL backgroundTouched = YES;

   for (UITouch *touch in touches) {
      CGPoint location = [touch locationInView:self];
      for (UITableViewCell *cell in self.visibleCells) {
         if (CGRectContainsPoint(cell.frame, location)) {
            backgroundTouched = NO;
            break;
         }
      }
   }

   if (backgroundTouched) {
      for (UITableViewCell *cell in self.visibleCells) {
         // This presumes the first subview is the text field you want to resign.
         [[cell.contentView.subviews objectAtIndex:0] resignFirstResponder];
      }
   }

   [super touchesBegan:touches withEvent:event];
}

0

Якщо ви хочете відхилити клавіатуру під час натискання клавіші повернення, ви можете просто додати наступний код у textField повинен повернути метод, тобто:

- (BOOL)textFieldShouldReturn:(UITextField *)atextField
{
   [textField resignFirstresponder];
}

У деяких текстових полях може бути подання вибору або інше як підпогляд, тому в цьому випадку вищевказаний метод не працює, тому в цьому випадку нам потрібно використовувати клас UITapGestureRecognizer, тобто додати наступний фрагмент коду до методу viewDidLoad, тобто:

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                          action:@selector(dismissKeyboard)];

    [self.view addGestureRecognizer:tap];

Тепер просто додайте відповідь відставки до методу вибору, тобто:

-(void)dismissKeyboard 
{
    [textField resignFirstResponder];
}

Сподіваюся, це допомагає, дякую :)


0

Багато цікавих відповідей. Я хотів би скласти різні підходи до рішення, яке, на мою думку, найкраще відповідає сценарію UITableView (саме той, який я зазвичай використовую): Те, що ми зазвичай хочемо, це в основному приховати клавіатуру за двома сценаріями: при натисканні назовні елементів Text UI, або прокручування вниз / вгору по UITableView. Перший сценарій ми можемо легко додати через TapGestureRecognizer, а другий через метод UIScrollViewDelegate scrollViewWillBeginDragging:. Перший порядок бізнесу, спосіб приховати клавіатуру:

   /**
     *  Shortcut for resigning all responders and pull-back the keyboard
     */
    -(void)hideKeyboard
    {
        //this convenience method on UITableView sends a nested message to all subviews, and they resign responders if they have hold of the keyboard
        [self.tableView endEditing:YES];

    }

Цей метод передає у відповідь будь-який інтерфейс текстового поля підпоглядом у межах ієрархії подання UITableView, тому це більш практично, ніж подавати у відставку кожен окремий елемент незалежно.

Далі ми піклуємось про звільнення за допомогою зовнішнього жесту натискання:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [self setupKeyboardDismissGestures];

}

- (void)setupKeyboardDismissGestures
{

//    Example for a swipe gesture recognizer. it was not set-up since we use scrollViewDelegate for dissmin-on-swiping, but it could be useful to keep in mind for views that do not inherit from UIScrollView
//    UISwipeGestureRecognizer *swipeUpGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
//    swipeUpGestureRecognizer.cancelsTouchesInView = NO;
//    swipeUpGestureRecognizer.direction = UISwipeGestureRecognizerDirectionUp;
//    [self.tableView addGestureRecognizer:swipeUpGestureRecognizer];

    UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
    //this prevents the gestureRecognizer to override other Taps, such as Cell Selection
    tapGestureRecognizer.cancelsTouchesInView = NO;
    [self.tableView addGestureRecognizer:tapGestureRecognizer];

}

Встановлення tapGestureRecognizer.cancelsTouchesInView на NO - це уникнути перекриття перебігом gestureRecognizer нормальних внутрішніх функцій UITableView (наприклад, не перешкоджати вибору комірок).

Нарешті, для обробки приховування клавіатури на Прокручування вгору / вниз по UITableView, ми повинні реалізувати протокол UIScrollViewDelegate протокол scrollViewWillBeginDragging: метод, як:

.h файл

@interface MyViewController : UIViewController <UIScrollViewDelegate>

.m файл

#pragma mark - UIScrollViewDelegate

-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    [self hideKeyboard];
}

Я сподіваюся, що це допомагає! =)


0

Ось як я нарешті зробив твори. Я поєднав пропозиції та коди з різних відповідей. Особливості: відхилення клавіатури, переміщення текстових полів над клавіатурою під час редагування та налаштування "Далі" та "Готово" тип повернення клавіатури. ЗАМЕЧАННЯ "..." з додатковими полями

static const CGFloat ANIMATION_DURATION = 0.4;
static const CGFloat LITTLE_SPACE = 5;
CGFloat animatedDistance;
CGSize keyboardSize;

@interface ViewController () <UITextFieldDelegate>
 @property (weak, nonatomic) IBOutlet UITextField *firstNameTXT;
  .....// some other text fields
 @property (weak, nonatomic) IBOutlet UITextField *emailTXT;
@end

@implementation ViewController
- (void)viewDidLoad{
.....
// add tap gesture to help in dismissing keyboard
UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc]
                                       initWithTarget:self
                                       action:@selector(tapScreen:)];// outside textfields

[self.view addGestureRecognizer:tapGesture];

// set text fields return key type to Next, last text field to Done
[self.firstNameTXT setReturnKeyType:UIReturnKeyNext];
.....
[self.emailTXT setReturnKeyType:UIReturnKeyDone];

// set text fields tags
[self.firstNameTXT setTag:0];
....// more text fields
[self.emailTXT setTag:5];

// add keyboard notification
[[NSNotificationCenter defaultCenter] addObserver:self     selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
}
[[NSNotificationCenter defaultCenter] addObserver:self      selector:@selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];
}

// dismiss keyboard when tap outside text fields
- (IBAction)tapScreen:(UITapGestureRecognizer *)sender {
  if([self.firstNameTXT isFirstResponder])[self.firstNameTXT resignFirstResponder];
  ...
  if([self.emailTXT isFirstResponder])[self.emailTXT  resignFirstResponder];

  }
- (BOOL)textFieldShouldReturn:(UITextField *)textField{
   if(textField.returnKeyType==UIReturnKeyNext) {
     // find the text field with next tag
     UIView *next = [[textField superview] viewWithTag:textField.tag+1];
     [next becomeFirstResponder];
   } else if (textField.returnKeyType==UIReturnKeyDone || textField.returnKeyType==UIReturnKeyDefault) {
    [textField resignFirstResponder];
 }
return YES;
}

// Moving current text field above keyboard
-(BOOL) textFieldShouldBeginEditing:(UITextField*)textField{
   CGRect viewFrame = self.view.frame;
   CGRect textFieldRect = [self.view.window convertRect:textField.bounds fromView:textField];
   CGRect viewRect = [self.view.window convertRect:self.view.bounds fromView:self.view];
   CGFloat textFieldBottomLine = textFieldRect.origin.y + textFieldRect.size.height + LITTLE_SPACE;//

   CGFloat keyboardHeight = keyboardSize.height;

   BOOL isTextFieldHidden = textFieldBottomLine > (viewRect.size.height - keyboardHeight)? TRUE :FALSE;
  if (isTextFieldHidden) {
    animatedDistance = textFieldBottomLine - (viewRect.size.height - keyboardHeight) ;
    viewFrame.origin.y -= animatedDistance;
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:ANIMATION_DURATION];
    [self.view setFrame:viewFrame];
    [UIView commitAnimations];
  }
  return YES;
}

-(void) restoreViewFrameOrigionYToZero{
  CGRect viewFrame = self.view.frame;
  if (viewFrame.origin.y != 0) {
    viewFrame.origin.y = 0;
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:ANIMATION_DURATION];
    [self.view setFrame:viewFrame];
    [UIView commitAnimations];
  }
}

-(void)keyboardDidShow:(NSNotification*)aNotification{
   NSDictionary* info = [aNotification userInfo];
   keyboardSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
 }

-(void)keyboardDidHide:(NSNotification*)aNotification{
   [self restoreViewFrameOrigionYToZero];// keyboard is dismissed, restore frame view to its  zero origin
}
@end

0

Відповідь @ mixca дуже корисна, але що робити, якщо у мене щось відмінне від UITextField. Я думаю, що найкращий спосіб впоратися з цим шляхом пошуку всіх підвидів основного виду з рекурсивною функцією, перевірте приклад нижче

- (BOOL)findAndResignFirstResponder {
if (self.isFirstResponder) {
    [self resignFirstResponder];
    return YES;
}

    for (UIView *subView in self.subviews) {
        if ([subView findAndResignFirstResponder]) {
            return YES;
        }
    }
    return NO;
}

а також ви можете помістити цей метод у свій клас корисності та використовувати його за допомогою жесту на кран, як відповідь @ mixca ..


0

Швидкий 4 / 4.2 / 5

Ви також можете відхилити клавіатуру при натисканні на клітинку - перш ніж робити що-небудь інше.

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    view.endEditing(true)
    // Do something here
    }

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.