Отключить клавиатуру, прикоснувшись к фону UITableView - PullRequest
100 голосов
/ 23 февраля 2010

У меня есть UITableView с UITextField с в качестве ячеек. Я хотел бы отклонить клавиатуру при прикосновении к фону UITableView. Я пытаюсь сделать это, создав UIButton размер UITableView и поместив его позади UITableView. Единственная проблема заключается в том, что UIButton ловит все касания, даже когда касание находится на UITableView. Что я делаю не так?

Спасибо!

Ответы [ 27 ]

5 голосов
/ 18 декабря 2015

У меня был UITableViewController, и реализация touchesBegan:withEvent: не работала для меня.

Вот что сработало:

Свифт:

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

Objective-C:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [self.view endEditing:YES];
}
4 голосов
/ 18 августа 2010
@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 голосов
/ 04 января 2014

Если вы ориентируетесь на iOS7, вы можете использовать один из следующих вариантов:

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;

Первый будет анимировать экранную клавиатуру при прокрутке табличного представления, а второй скрывает клавиатуру, как приложение «Стандартные сообщения».

Обратите внимание, что они из UIScrollView, которые UITableView наследуются от.

2 голосов
/ 22 мая 2012

У меня была такая же проблема, и вот мое решение, оно прекрасно работает для меня:

В контроллере вида или представления, который вы реализовали <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, чтобы перейти к вашему tableView, и вызовите addGestureRecognizer:

[self.superview.superview addGestureRecognizer:gestureRecognizer];

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

[self.superview.superview removeGestureRecognizer:gestureRecognizer];

Надеюсь, это поможет.

2 голосов
/ 28 августа 2010

UITableView является подклассом UIScrollView.

Я сделал так, чтобы прослушать событие прокрутки пользователем, а затем resignFirstResponder.Вот метод UIScrollViewDelegate для реализации в вашем коде:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView

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

2 голосов
/ 17 сентября 2014

Я нашел решение, которое прекрасно работает.

Необходим для использования UIGestureRecognizerDelegate и метода - gestRecognizer: shouldReceiveTouch: .

Добавьте распознаватель жестов в TableView следующим образом:

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

Затем реализуйте метод делегата shouldReceiveTouch , чтобы отклонять касания, выполняемые в классе UITableViewCell. Метод hideKeyboard будет вызываться только тогда, когда касание выполнено вне класса 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 голосов
/ 09 января 2014

Я хотел, чтобы моя ячейка открывала клавиатуру, когда была выбрана любая часть ячейки, и закрывала ее, если вы щелкнули где-нибудь вне ячейки. Чтобы открыть клавиатуру:

- (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];
    }
}
1 голос
/ 22 марта 2019

Попробуйте это:

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)

}
1 голос
/ 23 ноября 2011

Я искал решение и не нашел ничего, что соответствовало бы моему коду, поэтому я сделал это так:

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

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

1 голос
/ 28 мая 2014

Простое использование UITapGestureRecognizer и cancelsTouchesInView = NO означает, что нажатие на ячейки и UITextViews также вызывает скрытие. Это плохо, если у вас есть несколько UITextViews, и вы нажимаете на следующий. Клавиатура начнет скрываться, а затем следующий текстовый вид становится первым ответчиком, и клавиатура снова становится видимой. Чтобы избежать этого, проверьте местоположение касания и скрывайте клавиатуру, только если касание не находится в ячейке:

// 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 tableView должно быть YES

// Hide on scroll
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    [self.view endEditing:YES];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...