UITableViewCell dequeueReusableCellWithIdentifier:forIndexPath:issue

时间:2013-12-10 17:09:09

标签: ios uitableview

我想知道是否有人有类似的问题我最近在实验。

让我再向您描述一下我的问题。我有一个UITableViewController,我在IB中设计了一组自定义UITableViewCell。每个UITableViewCell都有不同的元素,如UIButton,UITextField和UILabel等。显然,每个UITableViewCell都有不同的标识符。

一旦定义了所有我的UITableViewCells,下一步就是在tableView上实例化单元格:cellForRowAtIndexPath:。我在这个方法中做的是依赖于section和row,我通过dequeueReusableCellWithIdentifier实例化不同的UITableViewCells:forIndexPath:。

一切似乎在桌面上完美正确地创建,但是当我向下滚动时问题就出现了。在最顶层,我有一个带有UIButton的UITableViewCell,我已经指定了一个具体的动作,当它被点击时执行。向下滚动,有几个UITableViewCell具有相同的格式(内部的UIButton指定了不同的动作)。

问题是,当点击底部的第一个按钮时,此按钮执行我在最顶层的UIButton上定义的第一个动作及其自己的动作。

似乎当uitableviewdelegate创建新单元格或重用它们时,它会嵌套来自其他indexPath而不是指定indexPath的函数....

希望我能正确解释自己。

提前谢谢。

[编辑]

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [[UITableViewCell alloc] init];

NSLog(@"indexpath value is: %@", indexPath);

if (indexPath.section == 0)
    cell = [self buildSection_0:tableView getIndexPath:indexPath];
else if (indexPath.section == 1)
    cell = [self buildSection_1:tableView getIndexPath:indexPath];
else if (indexPath.section == 2)
    cell = [self buildSection_2:tableView getIndexPath:indexPath];
else if (indexPath.section == 3)
    cell = [self buildSection_3:tableView getIndexPath:indexPath];
else if (indexPath.section == 4)
    cell = [self buildSection_4:tableView getIndexPath:indexPath];
return cell;
}

-(UITableViewCell *)buildSection_0:(UITableView *)tableView getIndexPath:(NSIndexPath *)indexPath{
NSString *identifier;
UITableViewCell *cell;

if (indexPath.row == 0){
    identifier = @"headerCell";
    cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
}
else if (indexPath.row == 1){
    identifier = @"buttonCell";
    cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
    UIButton *button = (UIButton *)[cell viewWithTag:3001];
    [button setTitle:@"Scan" forState:UIControlStateNormal];
    [button addTarget:self action:@selector(scan) forControlEvents:UIControlEventTouchUpInside];
}

return cell;
}

-(UITableViewCell *)buildSection_3:(UITableView *)tableView getIndexPath:(NSIndexPath *)indexPath{
NSString *identifier;
UITableViewCell *cell;

if (indexPath.row == [[job jobLocations] count]) { // Adding button insert more Locations
    identifier = @"buttonCell";
    cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
    UIButton *button = (UIButton *)[cell viewWithTag:3001];
    [button setTitle:@"Add Location" forState:UIControlStateNormal];
    [button addTarget:self action:@selector(newLocation) forControlEvents:UIControlEventTouchUpInside];
}
else{ // Showing different Locations
    identifier = @"locationCell";
    cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
    UILabel *label = (UILabel *)[cell viewWithTag:3007];
    UITextField *textField = (UITextField *)[cell viewWithTag:3008];

    [label setText:[NSString stringWithFormat:@"Location #%ld", (long)indexPath.row + 1]];
    [textField setText:[[[job jobLocations] objectAtIndex:indexPath.row] locationType]];
}

return cell;
}

2 个答案:

答案 0 :(得分:1)

dequeueReusableCellWithIdentifier:forIndexPath将重复使用不再可见的单元格,您可能希望在单元格上实现prepareForReuse,或在将其出列后重置它。

[编辑]

看到你添加了你的代码,你应该在添加新代码之前从按钮中删除以前的目标/动作,因为如果正在重用一个单元格,旧的代码/动作仍然存在:

[button removeTarget:self action:NULL forControlEvents:UIControlEventTouchUpInside];
[button addTarget:...

答案 1 :(得分:0)

在与indexPath.row对应的按钮上添加标签。然后在您的按钮操作方法中,您可以通过查看(UIButton *)sender标记来确定单击了哪个按钮。