2011-10-13 61 views
1

我有一个UITableView,其中只能剔除4个单元格。如果我勾选了一定数量的单元格然后向上或向下滚动,它将随机选择单元格。我不明白这背后的逻辑,因为我用于滴答的唯一方法是DidSelectRowAtIndex,它不会被执行(我在那里放置一个断点来检查它)。我真的不知道这可能是造成这一点,但这里是cellForRowAtIndex:当他们离开框架时,UITableView随机剔除细胞

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

     static NSString *cellName = @"PrefsTableViewCell"; 

     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: 
           cellName]; 
     if (cell == nil) 
     { 
       cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellName] autorelease]; 
     } 

     NSUInteger row = [indexPath row]; 
     Drink *drink = [drinks objectAtIndex:row]; 

     cell.textLabel.text = drink.name; 
     cell.detailTextLabel.text = [NSString stringWithFormat:@"%d", drink.caffeine]; 
     [[cell imageView] setImage:drink.image]; 

     return cell; 
} 

我有一种感觉,它有事情做的,但我真的不能告诉。

这是它看起来像之前滚动到:

enter image description here

这是当我滚动到顶部会发生什么:

enter image description here

我没有点击顶部一。如果我再次向下滚动,它可能会被取消,另一个会被打勾。

这可能是重要的,所以这里是didSelectRowAtIndexPath方法方法:

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

     NSLog(@"TESTING"); 

     if ((cell.accessoryType == UITableViewCellAccessoryNone) && [[DataContainerSingleton theDataContainerSingleton].favourites count] < 4) 
     { 
       cell.accessoryType = UITableViewCellAccessoryCheckmark; 

       [[DataContainerSingleton theDataContainerSingleton].favourites addObject:[drinks objectAtIndex:indexPath.row]]; 
       NSLog(@"CHECKED %d", [[DataContainerSingleton theDataContainerSingleton].favourites count]); 
     } 
     else if (cell.accessoryType == UITableViewCellAccessoryCheckmark) 
     { 
      for (int i = 0; i < [[DataContainerSingleton theDataContainerSingleton].favourites count]; i++) 
      { 
       NSString *drinkName = [[drinks objectAtIndex:indexPath.row] name]; 
       NSString *favName = [[[DataContainerSingleton theDataContainerSingleton].favourites objectAtIndex:i] name]; 

       if ([drinkName isEqualToString: favName]) 
       { 
        cell.accessoryType = UITableViewCellAccessoryNone; 
        [[DataContainerSingleton theDataContainerSingleton].favourites removeObjectAtIndex:i]; 
        NSLog(@"UNCHECKED %d", [[DataContainerSingleton theDataContainerSingleton].favourites count]); 
       } 
      } 

     } 
} 
+0

你是否会动态改变你的tableview的内容?或者它只加载一次? – booleanBoy

+0

它是动态更改的。每次向上或向下滚动新单元格进入屏幕时,cellForRowAtIndexPath会自动调用。 – JheeBz

回答

4

你是不是保存哪些物品已打勾。您应该将索引保存在数组中,并在cellForRowAtIndexPath:中设置勾号。一些喜欢 -

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    [tableView deselectRowAtIndexPath:indexPath animated:YES]; 

     if(![self.tickedIndexPaths containsObject:indexPath]) //tickedIndexPaths is an array 
      [self.tickedIndexPaths addObject:indexPath]; 
     else 
      [self.tickedIndexPaths removeObject:indexPath]; 
} 

然后 -

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

     static NSString *cellName = @"PrefsTableViewCell"; 

     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: 
           cellName]; 
     if (cell == nil) 
     { 
       cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellName] autorelease]; 
     } 

     NSUInteger row = [indexPath row]; 
     Drink *drink = [drinks objectAtIndex:row]; 

     cell.textLabel.text = drink.name; 
     cell.detailTextLabel.text = [NSString stringWithFormat:@"%d", drink.caffeine]; 
     [[cell imageView] setImage:drink.image]; 

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

     return cell; 
} 

请记住,由于电池的再利用,最后else块是非常重要的。

+0

我实际上做过这样的检查。我附加了didSelectRowAtIndexPath。 – JheeBz

+0

当你在'didSelect ...'中选择'accessoryType'时,你是绝对正确的。然而,按照'DataContainerSingleton',也必须将它设置在'cellFor ...'中。这是因为在滚动时单元格会重新使用,您需要将单元格的外观与模型类(DataContainerSingleton)重新同步。 – Akshay