UITableViewCell с UITextField теряет способность выбирать строку UITableView? - PullRequest
14 голосов
/ 05 июля 2011

Я почти закончил реализацию UITableViewCell с UITextField в нем. Вместо того, чтобы проходить через CGRectMake и UITableViewCell.contentView, я реализовал это более простым способом:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"Cell"];
    [cell setSelectionStyle:UITableViewCellSelectionStyleBlue];
    amountField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 190, 30)];
    amountField.placeholder = @"Enter amount";
    amountField.keyboardType = UIKeyboardTypeDecimalPad;
    amountField.textAlignment = UITextAlignmentRight;
    amountField.clearButtonMode = UITextFieldViewModeNever; 
    [amountField setDelegate:self];

    [[cell textLabel] setText:@"Amount"];
    [cell addSubview:amountField];
    return cell;
}

А затем я также реализовал метод didSelectRow, отказавшись от textField, чтобы показать другие поля ввода.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    ...
    [amountField resignFirstResponder];
    ...
}

Это работает гладко, единственное, что есть другие строки в таблице, когда эти другие выделены, вся ячейка выделена и становится синей, а та, что с моим UITextField - нет, я имею в виду, что поле выбрано, и я Можно ввести текст, но ячейка не выбрана. Я проверил это и выяснил, что проблема в строке:

[cell addSubview:amountField];

Кажется, что это нарушает поведение выбираемой ячейки, и даже добавление ее в [cell contentView] не исправляет это. Я что-то пропустил?

Ответы [ 5 ]

43 голосов
/ 05 июля 2011

Если текстовое поле имеет userInteractionEnabled , установленное на ДА , и оно заполняет всю ячейку, вы не можете заставить ячейку прослушивать прикосновения.Чтобы ячейка реагировала на прикосновения, вам нужно установить userInteractionEnabled текстового поля на NO .

Редактировать: И если вы хотите сделать текстовое поле редактируемым, при выделении ячейки добавьте следующий код в didSelectRowAtIndexPath: method,

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    // get the reference to the text field
    [textField setUserInteractionEnabled:YES];
    [textField becomeFirstResponder];
}
6 голосов
/ 05 июля 2011

Вы не сломали ничего, добавив подпредставление, вместо этого UITextField захватывает касание перед UITableViewCell. Вы можете проверить это, нажав за пределами UITextField, но в пределах UITableViewCell, и вы увидите, что он на самом деле все еще выбирает, как вы ожидаете.

Чтобы обойти это, вы можете создать подкласс UITextField и добавить свойство UITableView. Установите свойство, когда вы создаете экземпляр UITextField и добавляете его в ячейку.

amountField.tableView = tableView;

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

- (BOOL)becomeFirstResponder
{
    // Get the rect of the UITextView in the UITableView's coordinate system
    CGRect position = [self convertRect:self.frame toView:self.tableView];
    // Ask the UITableView for all the rows in that rect, in this case it should be 1
    NSArray *indexPaths = [self.tableView indexPathsForRowsInRect:position];
    // Then manually select it
    [self.tableView selectRowAtIndexPath:[indexPaths objectAtIndex:0] animated:YES scrollPosition:UITableViewScrollPositionNone];
    return YES;
}
1 голос
/ 01 июня 2015

внутри ячейки для строки по индексу

1 голос
/ 05 июля 2011

Прежде всего вам нужно было использовать reuseIdentifier для cellForRowAtIndexPath. Причина, по которой вы не используете reuseIdentifier, заключается в следующем: когда вы прокручиваете вверх и вниз, он всегда выделяет новую ячейку и новые текстовые поля, поэтому вам нужно поставить условие cell == nil,поэтому пересмотренный код здесь:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  static NSString *reuseIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if (cell==nil) {
    cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier] autorelease];

     UITextField *amountField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 190, 30)];
     amountField.placeholder = @"Enter amount";
     amountField.keyboardType = UIKeyboardTypeDecimalPad;
     amountField.textAlignment = UITextAlignmentRight;
     amountField.clearButtonMode = UITextFieldViewModeNever; 
     [amountField setDelegate:self];
     [cell.contentView addSubview:amountField];
}
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[[cell textLabel] setText:@"Amount"];

return cell;
}

В методе делегата didSelect вы можете сделать это следующим образом:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
  [prevField resignFirstResponder];
  UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
  UIView *view = [[cell.contentView subviews] lastObject];
  if([view isKindOfClass:[UITextField class]]{
     currentField = (UITextField*)view;
  }
  [currentField becomeFirstResponder];
  prevField = currentField;
}
1 голос
/ 05 июля 2011

Первое, что вы не использовали многоразовые клетки. Приведенная вами кодировка вызовет много памяти.

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

Одно решение для вашего квеста

В вашем textField Delegate

UITableViewCell *cell = (UITableViewCell *)[textField superView];
cell.selected=YES; //I think this will call the didSelectRowATIndex;

Я не уверен, что это сработает. Но стоит попробовать.

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