UITextField UITableViewCell内部 - 防止文本重置的方法

时间:2013-08-30 14:43:07

标签: ios uitextfield uitableview

我的UITableView足够高,需要滚动。表格中最顶部的单元格包含UITextField,供用户输入一些文本。

构建此标准的标准方法可能是创建和添加文本字段并将其添加到cellFOrRowAtIndexPath:中创建或回收的单元格中。但是,此常量重新创建意味着在字段中输入的文本将被删除当单元格滚动并返回视图时。

到目前为止,我发现的解决方案建议使用UITextField委派来跟踪文本,因为它会更改并将其存储在iVar或属性中。我想知道为什么建议这样做而不是我使用的更简单的方法:

我在UITextField的init方法中创建UITableViewController并立即将其存储在属性中。在cellFOrROwAtIndexPath中,我只是添加预先存在的字段,而不是初始化新字段。单元本身可以毫无问题地回收,但因为我总是使用唯一的UITextField,所以内容得以维护。

这是一种合理的方法吗?可能出什么问题?任何改进(也许我仍然可以在cellForRowAtIndexPath中创建字段,但首先检查属性是否为零?)

3 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:0)

如果只有一个UITextField,那么我同意你的方法与使用UITextField委托相比更好/相同(我认为)。

但是,我们假设您要“扩展”您的视图,以便现在有大约7-8个或更多的TextField。然后,如果您继续使用您的方法,那么问题是您将在内存中存储7-8个或更多TextField并维护它们。

在这种情况下,更好的方法是在屏幕上只创建可见数量的文本字段。然后创建一个字典,用于维护文本字段中的内容(可以通过UITextFieldDelegate方法获得)。这样,当重用单元时,可以使用相同的文本字段。只有值会发生变化,并且将由字典中的值决定。

在旁注中,在每个表滚动期间调用cellForRowAtIndexPath中的最小创建,因此在cellForRowAtIndexPath中创建textField可能很昂贵。

答案 2 :(得分: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];
}