2013-08-30 2 views
4

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

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

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

Я создаю UITextField в методе init метода UITableViewController и сразу же сохраняю его в свойстве. В cellFOrROwAtIndexPath Я просто добавляю ранее существовавшее поле вместо инициализации нового. Сама ячейка может быть переработана без проблем, но поскольку я всегда использую один и только UITextField, содержимое сохраняется.

Это разумный подход? Что может пойти не так? Любые улучшения (возможно, я мог бы создать поле в cellForRowAtIndexPath, но сначала проверить, является ли свойство нулем?)

ответ

1

При создании ячеек в cellForRowAtIndexPath вы должны использовать один многоразовый идентификатор для этой первой ячейки (т. Е. CellId1), а другой для остальных (т. Е. CellId2).

Если вы сделаете это, когда вы получите ячейку для первого элемента, вызвав [tableView dequeueReusableCellWithIdentifier:@"cellId1"], вы всегда получите тот же объект и не будете повторно использоваться другими ячейками.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    MyCell *cell = nil; 

    // Only for first row 
    if (indexPath.row == 0) { 
     static NSString *cellId1 = @"cellId1"; 
     cell = [tableView dequeueReusableCellWithIdentifier:cellId1]; 

     if (cell == nil) { 
      cell = [[MyCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId1]; 
     } 
    } 
    else { 
     static NSString *cellId2 = @"cellId2"; 
     cell = [tableView cellId2]; 

     if (cell == nil) { 
      cell = [[MyCell alloc] initWithStyle:UITableViewCellStyleDefault cellId2]; 
     } 
    } 

    // do whatever 

    return cell; 
} 
+0

Спасибо, но это не решает текстовое поле внедренный в ячейке. –

+0

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

+0

Вы совершенно правы - это лучше, чем использование init. Кроме того, я могу просто сохранить textview как свойство, а не ячейку. Во всяком случае, это еще раз подтверждает мой вопрос, потому что, если у меня было много текстовых меток, я все же считаю, что ваш подход лучше, чем использование делегирования. Надеюсь, кто-то объяснит, почему нет. –

0

Если есть только один UITextField, то я согласен с тем, что ваш подход будет лучше/то же, что и при использовании делегирования UITextField (Я думаю).

Однако предположим, что вы хотите «расширить» ваш вид, чтобы теперь было около 7-8 или более текстовых полей. Затем, если вы будете использовать свой подход, проблема будет заключаться в том, что вы будете хранить 7-8 или более текстовых полей в памяти и поддерживать их.

В такой ситуации лучшим подходом было бы то, что вы создаете только то количество текстовых полей, которые видны на экране. Затем вы создаете словарь, который будет поддерживать содержимое, присутствующее в текстовом поле (которое вы можете получить с помощью методов UITextFieldDelegate). Таким образом, одно и то же текстовое поле может использоваться, когда ячейка повторно используется. Только значения будут меняться и будут определяться значениями в словаре.

На боковой панели создайте минимальное создание в cellForRowAtIndexPath, как это называется во время каждой прокрутки таблицы, и поэтому создание текстового поля в cellForRowAtIndexPath может быть дорогостоящим.

0
#import "ViewController.h" 
#import "TxtFieldCell.h" 

#define NUMBER_OF_ROWS 26 

@interface ViewController()<UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate> 
@property (weak, nonatomic) IBOutlet UITableView *tablView; 
@end 

@implementation ViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.tablView.datasource = self; //set textfield delegate in storyboard 
    textFieldValuesArray = [[NSMutableArray alloc] init]; 
    for(int i=0; i<NUMBER_OF_ROWS; i++){ 
     [textFieldValuesArray addObject:@""]; 
    } 
} 

- (void)didReceiveMemoryWarning { 
    [super didReceiveMemoryWarning]; 
} 

#pragma mark - TableView Datasource 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    TxtFieldCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TxtFieldCellId" forIndexPath:indexPath]; 
    cell.txtField.tag = indexPath.row; 
    if (textFieldValuesArray.count > 0) { 
     NSString *strText = [textFieldValuesArray objectAtIndex:indexPath.row]; 

     cell.txtField.text = strText; 
    } 
    return cell; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    return NUMBER_OF_ROWS; 
} 

#pragma mark - TextField Delegate 

- (void)textFieldDidEndEditing:(UITextField *)textField { 

    [textFieldValuesArray replaceObjectAtIndex:textField.tag withObject:textField.text]; 
} 
Смежные вопросы