4

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

构建它的标准方法可能是创建和添加文本字段并将其添加到在中创建或回收的单元格中。cellFOrRowAtIndexPath:但是,这种不断的重新创建意味着当单元格向外和向后滚动时,在字段中输入的文本将被删除进入视野。

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

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

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

4

3 回答 3

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;
}
于 2013-08-30T15:31:46.303 回答
0

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

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

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

在旁注中,在 cellForRowAtIndexPath 中进行最少的创建,因为在每次表格滚动期间都会调用它,因此在 cellForRowAtIndexPath 中创建 textField 可能会很昂贵。

于 2013-08-30T15:11:49.737 回答
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];
}
于 2016-12-09T08:59:56.663 回答