UITableView reloadData автоматически вызывает resignFirstResponder - PullRequest
42 голосов
/ 20 июня 2011

У меня есть этот UITableView с пользовательскими ячейками, которые могут получать только предопределенные значения, поэтому я использую UIPickerView в качестве их inputView.Все будет хорошо, пока я не отредактирую поле и мне не нужно будет показывать его обновленное значение.

Чтобы сделать вещи более понятными и простыми в обслуживании, я сделал делегаты и источники данных отдельными классами и использую уведомления для их создания.взаимодействовать с tableView.Таким образом, после того, как значение было выбрано из UIPickerView, источник данных tableView получает уведомление и, в свою очередь, уведомляет основной ViewController, который содержит ссылку на tableView.Оттуда я звоню

[_tableView reloadData];

, и все, кажется, работает, за исключением того, что UIPickerView исчезает, я думаю, потому что ячейки регенерируются и где-то вызывается некоторый resignFirstResponder, или что-то в этом роде.Есть ли другой способ заставить tableView обновлять свои значения без необходимости реализовывать собственный метод где-нибудь, который это делает, что было бы довольно уродливо?

Ответы [ 13 ]

25 голосов
/ 20 июня 2011

Это читается как ожидаемое поведение - сборщик принадлежит определенной ячейке, эта ячейка перезагружается и больше не является первым респондентом.Я думаю, нужно было выбрать какой-либо конкретный элемент, чтобы средство выбора появилось, т. Е. Сделать его первым ответчиком.

Так что вам нужно либо сделать его первым ответчиком после перезагрузки, либообновить конкретную ячейку напрямую.

22 голосов
/ 28 октября 2011

добавление:

[yourSearchBar becomeFirstResponder];

после вашего:

[_tableView reloadData];

сделал трюк

13 голосов
/ 13 августа 2015

Я столкнулся с той же проблемой, ни один из приведенных выше ответов не работал идеально (я вижу, как клавиатура подпрыгивает вверх и вниз и т.1004 *

[tableView beginUpdates];
[tableView endUpdates]; 

это сработало для меня, строки таблицы обновляются и даже расширяются / уменьшаются (если вы динамически меняете высоту строк) с хорошей анимацией, и все это без отставки первого респондента или даже запуска с клавиатуры.
Это не будет прокручивать ваше табличное представление, чтобы соответствовать любой развернутой строке, поэтому я поместил фрагмент выше в специальный метод, например:

- (void)tableView:(UITableView *)tableView reloadRowWhileShowingKeyboard:(NSIndexPath *)indexPath 
{  
    [tableView beginUpdates];
    [tableView endUpdates]; 

    [tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
7 голосов
/ 24 сентября 2013

Я решил эту проблему, создав подкласс UITextView, переопределив - (BOOL) resignFirstResponder и добавив BOOL canResign.эта переменная устанавливается перед перезагрузкой данных и сбрасывается через некоторое время.

6 голосов
/ 09 мая 2013

Вы можете использовать этот подход, не самый лучший, но он работает:

// pass the responder to a temporary (hidden) textField
[_tmpTextField becomeFirstResponder];

// reload data
[_tableView reloadData];

// reloadData is definitely async... 
// so pass the responder back in a timed op
double delayInSeconds = 0.1;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    [_textField becomeFirstResponder];
});
3 голосов
/ 17 сентября 2015

Я поместил свой UISearchBar в отдельный раздел в UITableView. При запуске поиска я обновлял только те разделы, которые не содержат строку поиска.

- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
1 голос
/ 18 сентября 2014
customTextField.canResign = NO;
[self.tableView reloadData];
customTextField.canResign = YES;

Пользовательское текстовое поле получено из UITextField.

.h

@interface CustomTextField : UITextField
@property (nonatomic,assign) BOOL canResign;
@end

.m

- (BOOL)canResignFirstResponder
{
    return self.canResign;
}

Убедитесь, что ваше пользовательское текстовое поле не воссоздано при перезагрузке табличного представления.

0 голосов
/ 09 октября 2018

Я использую beginUpdate и endUpdate После завершения обновления, получить ячейку, содержащую текстовое поле, которое уже имеет фокус, и сделать его первым респондентом

    self.tableView.beginUpdates()
    self.tableView.reloadRows(at: [indexPath], with: .automatic)
    self.tableView.endUpdates()
    let newCell = self.tableView.cellForRow(at: indexPath)
    newCell.textField.becomeFirstResponder()
0 голосов
/ 19 июля 2018

Отследите, какая клавиатура ячейки активна, а затем получите эту конкретную ячейку по cellForRowAtIndexPath и сделайте textView firstResponder

self.tableView.reloadData()
if let indexPath = self.activeIndexPath{
   if let cell = createFormTableView.cellForRow(at: indexPath) as? TextViewTableViewCell {
        cell.txtViewInput.becomeFirstResponder()
   }
}
0 голосов
/ 09 апреля 2018

Быстрое решение:

мы можем переопределить canResignFirstResponder по умолчанию, создав подкласс UITextfiled

class CustomField: UITextField{
    var canResign:Bool = false
    override var canResignFirstResponder: Bool{
        return canResign
    }  
}

все, что вам нужно для установки переменной canResign до и после оператора перезагрузки.

cell.offerInputTextField.canResign = false
tableView.reloadData()
cell.offerInputTextField.canResign = true

не забудьте назначить текстовое поле пользовательского класса как CustomField.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...