2012-01-13 5 views
2

У меня есть вопрос относительно подходящего вида.Как разрешить пользователю изменять текст в ячейках UITableView

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

Мой вопрос:

  1. , что я должен сделать для того, чтобы представить, что текстовое поле в клетках.

  2. Какие методы мне нужно реализовать, чтобы представить это текстовое поле в представлении таблицы в режиме редактирования.

  3. Как только я закончил с редактированием, как я могу обновить данные, которые находятся в контроллере представления контактов (содержит все контакты). Сохранение должно сохраняться в адресной книге. По этому вопросу я знаю, что мне нужно реализовать некоторый метод делегата, но я не уверен, как это сделать.

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

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath 
{ 
[tableView setSeparatorColor:[UIColor clearColor]]; 
//[self.tableView setEditing: YES animated: YES]; 


static NSString *CellIdentifier = @"Cell"; 

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"]; 
if (cell == nil) { 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 
} 

// Configure the cell... 
if(isEditingOn) { 

if(cell == nil) 
     cell = [self getCellContentView:CellIdentifier]; 
    UILabel *lblTemp1 = (UILabel *)[cell viewWithTag:1]; 
    UITextField *textfield1=(UITextField*)[cell viewWithTag:2]; 

if(indexPath.row == 0) { 
     lblTemp1.text = @"Name"; 
     textfield1.text = myContact.name; 
    } 

else if(indexPath.row == 1) { 
     lblTemp1.text = @"Phone"; 
     textfield1.text = myContact.phone; 
    } 

else if(indexPath.row == 2) { 
     lblTemp1.text = @"Email"; 
     textfield1.text = myContact.email; 
} 

} 

else {  

if(indexPath.row == 0) { 
    cell.textLabel.text = myContact.name; 
} 

else if(indexPath.row == 1) { 
    cell.textLabel.text = myContact.phone; 
} 

else if(indexPath.row == 2) { 
    cell.textLabel.text = myContact.email; 
} 
} 


return cell; 

}

- (UITableViewCell *) getCellContentView:(NSString *)cellIdentifier { 

CGRect CellFrame = CGRectMake(0, 0, 60, 20); 
CGRect Label1Frame = CGRectMake(10, 10, 180, 25); 
UILabel *lblTemp; 
UITableViewCell *cell = [[[UITableViewCell alloc] initWithFrame:CellFrame reuseIdentifier:cellIdentifier] autorelease]; 
lblTemp = [[UILabel alloc] initWithFrame:Label1Frame]; 
lblTemp.tag = 1; 
[cell.contentView addSubview:lblTemp]; 
[lblTemp release]; 
CGRect TextFieldFrame=CGRectMake(240, 10, 60, 25); 
UITextField *textfield; 
textfield=[[UITextField alloc]initWithFrame:TextFieldFrame]; 
textfield.tag=2; 
textfield.placeholder = @""; 
[cell.contentView addSubview:textfield]; 

} 
+0

В Xcode 4 вы можете использовать статическую конфигурацию ячейки таблицы и связать текстовые поля как IBOutlets. Почти нулевой код. – cocoafan

ответ

5

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

1) Добавьте UITextField в качестве подзона вашей ячейки таблицы, когда вы создаете ячейку в методе tableView: cellForRowAtIndexPath: (я полагаю, для этого используется метод getCellContentView:). Установите тег на свой UITextField, который соответствует индексу строки ячейки, и сделайте ваш tableviewcontroller делегатом для ячейки. Установите скрытое текстовое поле. (не забудьте установить тег каждый раз, когда запрашивается ячейка, а не только в первый раз, когда вы ее создали).

2) В таблицеView: didSelectRowAtIndexPath: метод, захватите ячейку с помощью tableViewCellForRowAtIndexPath, а затем покажите текстовое поле внутри нее (возможно, вам придется пройти через какой-либо обход для просмотра) и вызовите startFirstResponder в текстовое поле.

3) Когда пользователь набрал что-то, ваши методы textfielddelegate будут запущены. Вы можете посмотреть тег в текстовом поле, чтобы определить, к какой строке принадлежит это поле, а затем обновить источник dat новым текстом. Затем просто перезагрузите таблицу, чтобы скрыть текстовое поле и обновить содержимое ячейки.

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

Кроме того, tableView: didSelectRowAtIndexPath: обычно не запускается, когда просмотр таблицы находится в режиме редактирования, если вы не установите tableView.allowsSelectionDuringEditing = YES;

+0

Спасибо за ваше четкое объяснение. Но моя проблема заключается в методе cellForRowAtIndexPath, когда он находится в режиме редактирования, представление не отображается, как я хочу. Я хочу, чтобы мое редактируемое представление отображало имя, номер телефона, электронную почту (эти 3 являются постоянными для каждого контакта) в ярлыке в левой части ячейки и соответствующие значения в текстовом поле в правой части ячейки. Я думаю, что вы можете получить меня правильно. Когда представление находится в режиме редактирования, оно все еще показывает одни и те же данные с теми же данными без метки и текстового поля. – jessy

+0

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

1

Лучше использовать 2 UITableViewCell s, Первый для view и последний для edit.

Также мы будем зависеть от переменной rowToEdit, которая относится к текущей строке редактирования. (В моем случае одна ячейки имеет право быть отредактирована в то же время)

начнёе:

  1. Сначала я завишу от accessoryButtonTap действий, чтобы изменить строку:

    var rowToEdit: IndexPath? = nil 
    
    override func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath) { 
        // End edit mode if one cell being in edit mode other than this one 
        if let row = self.rowToEdit { 
        // return current edit cell to view mode 
        self.rowToEdit = nil 
        self.tableView.reloadRows(at: [row], with: .automatic) 
        } 
    
        self.rowToEdit = indexPath 
        self.tableView.reloadRows(at: [self.rowToEdit!], with: .automatic) 
    } 
    
  2. Разделите два режима при загрузке ячейки:

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
        if indexPath == self.rowToEdit { 
        let cellId = "ContactEditTableViewCell" 
        let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath as IndexPath) as! ContactEditTableViewCell 
        cell.accessoryType = .none 
        self.configEditCell(cell: cell, indexPath: indexPath) 
        return cell 
        } else { 
        let cellId = "ContactTableViewCell" 
        let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath as IndexPath) as! ContactTableViewCell 
    
        self.configCell(cell: cell, indexPath: indexPath) 
        return cell 
        } 
    } 
    
  3. Дополнительный вариант, если вы хотите изменить высоту на основе режима:

    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 
        if indexPath == self.rowToEdit { 
        return 120 
        } else { 
        return 70 
        } 
    } 
    
  4. Последний вариант, чтобы добавить Save и Cancel кнопки: я добавил их к каждому cell, поэтому я передать ссылку на ContactTable каждому клетка.

    @IBAction func btnSave_click(_ sender: UIButton) { 
        // save the record 
    
        btnCancel_click(sender) 
    } 
    
    @IBAction func btnCancel_click(_ sender: UIButton) { 
        let tmp = self.tbl.rowToEdit 
        self.tbl.rowToEdit = nil 
        self.tbl.tableView.reloadRows(at: [tmp!], with: .automatic) 
    } 
    

    Screenshot

Смежные вопросы