滚动屏幕时UITableViewCellAccessory消失

时间:2011-04-29 01:48:21

标签: iphone ios uitableview ios4

我有一个充满对象的UITableView。在 didSelectRowAtIndexPath 方法中,我选择了行时显示UITableViewCellAccessoryCheckmark,取消选择时消失。

下面是 didSelectRowAtIndexPath 方法的代码:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
 UITableViewCell *curCell = [beerTable cellForRowAtIndexPath:indexPath];

if (curCell.accessoryType == UITableViewCellAccessoryCheckmark) {
    [curCell setAccessoryType:UITableViewCellAccessoryNone];
    compareCount = (compareCount - 1);

    if (tableView == [[self searchDisplayController] searchResultsTableView]) {
        NSString *objBeer = [searchResults objectAtIndex:indexPath.row];
        [compareBeers removeObject:[searchResults objectAtIndex:indexPath.row]];
        [compareCarbs removeObject:[carbAmount objectAtIndex:[beerNames indexOfObject:objBeer]]];
    }
    else {
        [compareBeers removeObject:[beerNames objectAtIndex:indexPath.row]];
        [compareCarbs removeObject:[carbAmount objectAtIndex:indexPath.row]];
    }

}
else {
    [curCell setAccessoryType:UITableViewCellAccessoryCheckmark];
    compareCount = (compareCount + 1);

    if (tableView == [[self searchDisplayController] searchResultsTableView]) {
        NSString *objBeer = [searchResults objectAtIndex:indexPath.row];
        [compareBeers addObject:[searchResults objectAtIndex:indexPath.row]];
        [compareCarbs addObject:[carbAmount objectAtIndex:[beerNames indexOfObject:objBeer]]];
    }
    else {
        [compareBeers addObject:[beerNames objectAtIndex:indexPath.row]];
        [compareCarbs addObject:[carbAmount objectAtIndex:indexPath.row]];
    }

}

if (compareCount > 0) {
    if (compareOn == YES){
    }
    else {
    compareButton.enabled = YES;
    UIImage *image = [UIImage imageNamed:@"redbutton.png"];
    [compareButton setImage:image];
    }
}

else {
    compareButton.enabled = NO;
    [compareButton setImage:nil];
    [compareButton setCustomView:nil];
}

}

我也将此作为我的 cellForIndexPath

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


static NSString *CellIdentifier = @"CustomCell";

CustomCell *cell = (CustomCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {

    NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];

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

// Setting separate tables correctly....


return cell;
}

我的问题是,当所选单元格滚出视图时,与该值关联的复选标记现在在返回视图时消失。

如何防止Checkmark消失?

由于

5 个答案:

答案 0 :(得分:4)

滚动数据时,您的单元格会被重复使用(这就是dequeueReusableCellWithIdentifier所做的)。在didSelectRowAtIndexPath中获得复选标记的单元格将被回收用于不同的行,并且不再与已检查的行有任何连接。

您需要在cellForRowAtIndexPath中设置/取消设置附件视图,以便当选中的行滚动回视图时,会对它们进行适当的检查。

答案 1 :(得分:1)

对于任何想要更通用的方法和多个选定单元格的人

首先创建一个(NSMutableArray *)selectedCells来跟踪所选单元格。 接下来实现2个委托方法

-(void)tableView:(UITableView *)tableView 
    didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

//add the checkmark to cell when selected
if ([tableView cellForRowAtIndexPath:indexPath].accessoryType == UITableViewCellAccessoryNone){
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;

}

//once selected add that selected cell to the selectedCells array 

[self.selectedCells addObject:@(indexPath.row) ];

}

-(void)tableView:(UITableView *)tableView 
                 didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{ 

//set the accessory type back to none 
if([tableView cellForRowAtIndexPath:indexPath].accessoryType == UITableViewCellAccessoryCheckmark){
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
}

//remove the selected cells index from the selectedCells array
[self.selectedCells removeObject:@(indexPath.row) ];

}

现在,当您选择一个单元格时,会添加一个复选标记,并将indexPath.row存储到NSMutableArray中。当您取消选择该单元格时,它会删除复选标记并将其从数组中删除。这意味着数组将只保留被检查的单元格。

然后我们使用该数组在cellForRowAtIndexPath方法中为单元格提供正确的accessoryType。每当tableView需要一个单元格时,就会调用此方法,我们告诉它,在创建或不创建时需要创建checkMark。

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

 static NSString *CellIdentifier = @"Cell";
 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {
  cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];

//Create an NSNumber to hold the row of the cell to be created   
   NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:indexPath.row];

//then ask the array if the selectedCells array has that object.
//if it does then that cell needs a checkmark when created.

if ([self.selectedCells containsObject:rowNsNum]){
   cell.accessoryType = UITableViewCellAccessoryCheckmark;
     }
else { cell.accessoryType = UITableViewCellAccessoryNone;
     }

    [cell.textLabel setText:@"your contents"];
 }

 return cell;
 }

答案 2 :(得分:0)

滚动时可以回收UITableViewCell。因此,当您向下和向上滚动tableView时,您看到的单元格可能与先前可见的单元格不同。

您需要每次在cellForRowAtIndexPath中重置单元格的状态。您的代码有此注释区域 //正确设置单独的表....

这是您进行设置的地方。调用此选项时,请检查该单元格是否应显示复选标记,并相应地进行设置

答案 3 :(得分:0)

尝试在didSelectRow方法中为选定单元格的数组或字典中存储所选索引,并在cellForRowAtIndexPath中检查该索引是否在数组中可用,然后使用设置accesoryType对单元格进行复选标记。希望你理解

答案 4 :(得分:0)

这是我发现最好的方法:

(“添加此”和“结束添加”之间的任何代码)

另外,请确保将“(您的Number ofRows)”更改为返回int的对象,或者是int本身。例如myCustomArray.count,或24。

//In .h file add this
NSMutableArray *indexArray;

//in .m file 

- (void)viewDidLoad {
    //Add this
    indexArray = [[NSMutableArray alloc] init];
    int i;
    for (i = 0; i <= (Your Number ofRows); i++) {
        [indexArray addObject:[NSNumber numberWithDouble:0]];
    }
NSLog(@"indexArray = %@",indexArray);//You can check the console now to see if you have an array of "zeros" 
    //End Add this
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
UITableViewCell *curCell = [beerTable cellForRowAtIndexPath:indexPath];


if (curCell.accessoryType == UITableViewCellAccessoryCheckmark) {
    [curCell setAccessoryType:UITableViewCellAccessoryNone];
    compareCount = (compareCount - 1);

    //Add this
    [indexArray replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithDouble:0]]; 
    //End Add this


    if (tableView == [[self searchDisplayController] searchResultsTableView]) {
        NSString *objBeer = [searchResults objectAtIndex:indexPath.row];
        [compareBeers removeObject:[searchResults objectAtIndex:indexPath.row]];
        [compareCarbs removeObject:[carbAmount objectAtIndex:[beerNames indexOfObject:objBeer]]];
    }
    else {
        [compareBeers removeObject:[beerNames objectAtIndex:indexPath.row]];
        [compareCarbs removeObject:[carbAmount objectAtIndex:indexPath.row]];
    }

}
else {
    [curCell setAccessoryType:UITableViewCellAccessoryCheckmark];
    compareCount = (compareCount + 1);

    //Add this
    [indexArray replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithDouble:1]]; 
    //End Add this

    if (tableView == [[self searchDisplayController] searchResultsTableView]) {
        NSString *objBeer = [searchResults objectAtIndex:indexPath.row];
        [compareBeers addObject:[searchResults objectAtIndex:indexPath.row]];
        [compareCarbs addObject:[carbAmount objectAtIndex:[beerNames indexOfObject:objBeer]]];
    }
    else {
        [compareBeers addObject:[beerNames objectAtIndex:indexPath.row]];
        [compareCarbs addObject:[carbAmount objectAtIndex:indexPath.row]];
    }

}

if (compareCount > 0) {
    if (compareOn == YES){
    }
    else {
        compareButton.enabled = YES;
        UIImage *image = [UIImage imageNamed:@"redbutton.png"];
        [compareButton setImage:image];
    }
}

else {
    compareButton.enabled = NO;
    [compareButton setImage:nil];
    [compareButton setCustomView:nil];
}

}    



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


static NSString *CellIdentifier = @"CustomCell";

CustomCell *cell = (CustomCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {

    NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];

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

// Setting separate tables correctly....

//Add this
if ([[indexArray objectAtIndex:indexPath.row] doubleValue] == 1) {
    cell.accesoryType = UITableViewCellAccesoryTypeCheckmark;
} else {
    cell.accesoryType = UITableViewCellAccesoryTypeNone; 
}
//End Add this 

return cell;
}