UITableViewCell с UITextField теряют возможность выбора строки UITableView?

Я почти сделал реализацию 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] не устраняет это. Я что-то пропустил?

Ответ 1

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

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

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

    // get the reference to the text field
    [textField setUserInteractionEnabled:YES];
    [textField becomeFirstResponder];
}

Ответ 2

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

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

amountField.tableView = tableView;

Затем вам необходимо переопределить startFirstResponder в вашем подклассе, а в методе получить строку для ячейки с UITextField, а затем выбрать ее вручную

- (BOOL)becomeFirstResponder
{
    // Get the rect of the UITextView in the UITableView 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;
}

Ответ 3

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

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

Одним из решений для ваших вопросов является

В вашем текстовом делегате

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

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

Ответ 4

Прежде всего вам нужно было использовать 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 delegate вы можете сделать это

- (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;
}

Ответ 5

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

- (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"];

    **for (UIView *cellSubViews in cell.subviews) {
            cellSubViews.userInteractionEnabled = NO;
    }**

    [cell addSubview:amountField];
    return cell;
}

попробуйте это, он будет работать