iPhone 的 Objective-C 单元格中 UITextField 的滚动问题

发布于 2024-09-28 18:10:41 字数 1056 浏览 3 评论 0原文

我有以下问题:我有一个带有 7 个自定义单元格的 UITableView。每个单元格中都包含一个标签和一个 UITextField。由于单元格有点大,您必须向下滚动才能看到最后 3 个单元格。问题是,一旦我向下滚动,前 3 个单元格的文本字段中的文本(那些当时不可见的单元格)就会被删除。剩下的就是占位符。当我向上滚动时,最后 3 个单元格也是如此。第四个单元格中的文本字段可以很好地保留其文本,因为它始终可见。 有谁知道如何解决这个问题?

此致。

更新:这是相应评论的代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = @"NewXYZTableCell";

NewXYZTableCell *cell = (NewXYZTableCell*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil){
    NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"NewXYZTableCell" owner:nil options:nil];

    for(id currentObject in topLevelObjects)
    {
        if([currentObject isKindOfClass:[NewXYZTableCell class]])
        {
            cell = (NewXYZTableCell *)currentObject;
            break;
        }
    }
}

switch (indexPath.row) {            
    case 0:
        cell.myLabel.text = @"XYZ";
        // and so on... 
    default:
        break;
}   
return cell;}

I have following problem: I've got an UITableView with 7 custom cells. Each of these cells hold a label and an UITextField in it. Since the cells are somewhat big, you have to scroll down to see the last 3 cells. The problem is, as soon as I scroll down, the text in the textfields of the first 3 cells (those, that aren't visible then) gets removed. All that is left is the placeholder. The same goes for the last 3 cells, as soon as I scroll back up. The textfield in the 4th cell retains its text just fine, since its always visible.
Does anyone have an idea how to solve this problem?

Best regards.

UPDATE: Here's the code for the corresponding comment:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = @"NewXYZTableCell";

NewXYZTableCell *cell = (NewXYZTableCell*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil){
    NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"NewXYZTableCell" owner:nil options:nil];

    for(id currentObject in topLevelObjects)
    {
        if([currentObject isKindOfClass:[NewXYZTableCell class]])
        {
            cell = (NewXYZTableCell *)currentObject;
            break;
        }
    }
}

switch (indexPath.row) {            
    case 0:
        cell.myLabel.text = @"XYZ";
        // and so on... 
    default:
        break;
}   
return cell;}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

今天小雨转甜 2024-10-05 18:10:41

您可能使用出队机制用其单元格填充 UITableView。这意味着已分配且当前不在屏幕上的单元格可以重用并填充其他内容。这可以节省为每行分配新单元格的性能成本。因此,即使具有大量单元格的表格视图也可以表现得很好,因为它只需要同时处理六个或七个单元格。

这可能也发生在你身上。您的单元格会滚动出屏幕,现在可以由进入屏幕的新单元格重复使用(显示不同的内容)。因此,您将拥有另一个标题和另一个(新)文本字段。因此,如果单元格滚动出屏幕,您需要将输入保存在某处。例如,您可以监听 UITextFieldTextDidChangeNotification

将您的控制器注册为观察者,例如在 -viewDidLoad 中:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldChanged:) name:UITextFieldTextDidChangeNotification object:textField]

然后实现您的方法,在本例中是 textFieldChanged:,它需要一个 NSNotification* 作为参数并保存您的输入:

-(void)textFieldChanged:(NSNotification *)notification {
    ...
}

如果单元格在屏幕上向后滚动,请不要忘记将输入重新插入到单元格中。

另一种选择是不使用出队并在需要时立即创建所有单元。如果您只有很少的单元格,这可能是一个更好的主意。然后您需要注意在 -cellForRowAtIndexPath: 中返回正确的单元格。

You probably use the dequeueing mechanism to populate the UITableView with its cells. This means that a cell that has been allocated and is currently off the screen can be reused and filled with other content. This saves you the performance costs of allocating a new cell for each row. So even table views with a lot of cells can perform very well, because it only has to deal with, say, six or seven cells at the same time.

And this probably is also what happens to you. Your cells get scrolled off the screen and are now free to be reused by the new cells coming to the screen (displaying different contents). So you will have another title and another (new) text field. So you need to save your input somewhere if a cell gets scrolled off the screen. For example, you can listen to a UITextFieldTextDidChangeNotification.

Register your controller as an observer, e.g. in -viewDidLoad:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldChanged:) name:UITextFieldTextDidChangeNotification object:textField]

And then implement your method, in this case textFieldChanged:, which takes an NSNotification* as parameter and save your input:

-(void)textFieldChanged:(NSNotification *)notification {
    ...
}

Don't forget to reinsert the input to your cells if they are scrolled back on the screen.

Another option is to not use dequeueing and create all cells as soon as they are needed. This might be a better idea if you have only very few cells. You need to take care then to return the correct cell in -cellForRowAtIndexPath:.

瑾夏年华 2024-10-05 18:10:41

将其作为新答案发布,以便我可以使用代码格式。

我的建议是将七个单元格保存在七个实例变量中并创建适当的 getter。因此,在 .h 文件中声明变量:

NewXYZTableCell *cell0;
...
NewXYZTableCell *cell6;

在实现中,编写一个 getter:

-(NewXYZTableCell*) getCellNumber:(int)cellNumber {
    NewXYZTableCell *cell;
    switch (cellNumber)
    {
        case 0:
            cell = cell0;
            break,

        ...

        case 6:
            cell = cell6;
            break,
    }

    if (cell == nil){
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"NewXYZTableCell" owner:nil options:nil];

        for(id currentObject in topLevelObjects)
        {
            if([currentObject isKindOfClass:[NewXYZTableCell class]])
            {
                cell = (NewXYZTableCell *)currentObject;
                break;
            }
        }
    }
    return cell;
}

此 getter 将在创建单元格后返回具有相应编号的单元格(如果该单元格之前不存在)。然后您可以在 -tableView:cellForRowAtIndexPath: 中使用它:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
    return [self getCellNumber:indexpath.row];
}

Posting this as new answer, so I can make use of code formatting.

My suggestion is to save the seven cells in seven instance variables and create the appropriate getters. So, in your .h file you declare the variables:

NewXYZTableCell *cell0;
...
NewXYZTableCell *cell6;

In your implementation, write a getter:

-(NewXYZTableCell*) getCellNumber:(int)cellNumber {
    NewXYZTableCell *cell;
    switch (cellNumber)
    {
        case 0:
            cell = cell0;
            break,

        ...

        case 6:
            cell = cell6;
            break,
    }

    if (cell == nil){
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"NewXYZTableCell" owner:nil options:nil];

        for(id currentObject in topLevelObjects)
        {
            if([currentObject isKindOfClass:[NewXYZTableCell class]])
            {
                cell = (NewXYZTableCell *)currentObject;
                break;
            }
        }
    }
    return cell;
}

This getter will return the cell with the corresponding number after creating it, if it did not exist before. Then you can make use of it in -tableView:cellForRowAtIndexPath::

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
    return [self getCellNumber:indexpath.row];
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文