UITableViewCell选择子视觉鬼

问题描述:

我正在学习有关iPhone SDK,并有一个有趣的例外与UITableViewCell子视图管理时,手指按在一些行上。UITableViewCell选择子视觉鬼

该表用于为手势分配声音 - 在3个方向中的一个方向上滑动手机会触发声音播放。选择一行将显示一个包含4个声音分配选项的操作表:左,下,右和取消。声音可以映射到一个,两个或三个方向,因此任何单元格都可以具有七种状态之一:左,下,右,左和下,左和右,下和右或左和右。如果一行被映射到这七个状态中的任何一个,则相应的一个或多个箭头作为子视图显示在该行的边界内。箭头在给定的屏幕和滚动时来去去去。

但是,在滚动到一批新的行后,只有当我在某些(但不是全部)行上按下手指时,箭头才会奇迹般地出现在所选状态背景中。当我将手指从行中抬起并出现操作表时,箭头消失。按下任意四个按钮之后,我无法再复制这个。但是看到这个箭头在屏幕上闪烁,因为选定的行没有被分配给任何东西,所以很迷惑和困惑。

我还没有想过在这里看到什么?我所有的表格代码都粘贴在下面,这是问题的屏幕录像:http://www.screencast.com/users/JonathanGCohen/folders/Jing/media/d483fe31-05b5-4c24-ab4d-70de4ff3a0bf

我是否管理我的子视图有错误或者是否存在我缺少的选定状态属性?还有别的吗?我是否应该在这篇文章中包含更多信息以使事情更清楚?谢谢!!

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

    NSUInteger section = [indexPath section]; 
    NSUInteger row = [indexPath row]; 
    NSString *key = [categories objectAtIndex:section]; 
    NSArray *nameSection = [categoriesSounds objectForKey:key]; 
    static NSString *SectionsTableIdentifier = @"SectionsTableIdentifier"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: 
          SectionsTableIdentifier]; 
    NSArray *sound = [categoriesSounds objectForKey:key]; 
    NSString *soundName = [[sound objectAtIndex: row] objectAtIndex: 0]; 
    NSString *soundOfType = [[sound objectAtIndex: row] objectAtIndex: 1]; 

    if (cell == nil) { 
     cell = [[[UITableViewCell alloc] 
       initWithStyle:UITableViewCellStyleDefault 
       reuseIdentifier:SectionsTableIdentifier] autorelease]; 
    } 

    cell.textLabel.text = [[nameSection objectAtIndex:row] objectAtIndex: 0]; 

    NSUInteger soundSection = [[[sound objectAtIndex: row] objectAtIndex: 2] integerValue]; 
    NSUInteger soundRow = [[[sound objectAtIndex: row] objectAtIndex: 3] integerValue]; 

     NSUInteger leftRow = [leftOldIndexPath row]; 
     NSUInteger leftSection = [leftOldIndexPath section]; 
     if (soundRow == leftRow && soundSection == leftSection && leftOldIndexPath !=nil){ 
      [selectedSoundLeftAndDown removeFromSuperview]; 
      [selectedSoundLeftAndRight removeFromSuperview]; 
      [cell.contentView addSubview: selectedSoundLeft]; 
      selectedSoundLeft.frame = CGRectMake(200,8,30,30); 
     } 
     else { 
      [cell.contentView sendSubviewToBack: selectedSoundLeft]; 
     } 

     NSUInteger downRow = [downOldIndexPath row]; 
     NSUInteger downSection = [downOldIndexPath section]; 
     if (soundRow == downRow && soundSection == downSection && downOldIndexPath !=nil){ 
      [selectedSoundLeftAndDown removeFromSuperview]; 
      [selectedSoundDownAndRight removeFromSuperview]; 
      [cell.contentView addSubview: selectedSoundDown]; 
      selectedSoundDown.frame = CGRectMake(200,8,30,30); 
     } 
     else { 
      [cell.contentView sendSubviewToBack: selectedSoundDown]; 
     } 

     NSUInteger rightRow = [rightOldIndexPath row]; 
     NSUInteger rightSection = [rightOldIndexPath section]; 
     if (soundRow == rightRow && soundSection == rightSection && rightOldIndexPath !=nil){ 
      [selectedSoundDownAndRight removeFromSuperview]; 
      [selectedSoundLeftAndRight removeFromSuperview]; 
      [cell.contentView addSubview: selectedSoundRight]; 
      selectedSoundRight.frame = CGRectMake(200,8,30,30); 
     } 
     else { 
      [cell.contentView sendSubviewToBack: selectedSoundRight]; 
     } 

     // combos 
     if (soundRow == leftRow && soundRow == downRow && 
      soundSection == leftSection && soundSection == downSection){ 
      [selectedSoundLeft removeFromSuperview]; 
      [selectedSoundDown removeFromSuperview]; 
      [selectedSoundLeftAndDownAndRight removeFromSuperview]; 
      [cell.contentView addSubview: selectedSoundLeftAndDown]; 
      selectedSoundLeftAndDown.frame = CGRectMake(200,8,30,30); 
     } 
     else { 
      [cell.contentView sendSubviewToBack: selectedSoundLeftAndDown]; 
     } 
     if (soundRow == leftRow && soundRow == rightRow && 
      soundSection == leftSection && soundSection == rightSection){ 
      [selectedSoundLeft removeFromSuperview]; 
      [selectedSoundRight removeFromSuperview]; 
      [selectedSoundLeftAndDownAndRight removeFromSuperview]; 
      [cell.contentView addSubview: selectedSoundLeftAndRight]; 
      selectedSoundLeftAndRight.frame = CGRectMake(200,8,30,30); 
     } 
     else { 
      [cell.contentView sendSubviewToBack: selectedSoundLeftAndRight]; 
     } 
     if (soundRow == downRow && soundRow == rightRow && 
      soundSection == downSection && soundSection == rightSection){ 
      [selectedSoundDown removeFromSuperview]; 
      [selectedSoundRight removeFromSuperview]; 
      [selectedSoundLeftAndDownAndRight removeFromSuperview]; 
      [cell.contentView addSubview: selectedSoundDownAndRight]; 
      selectedSoundDownAndRight.frame = CGRectMake(200,8,30,30); 
     } 
     else { 
      [cell.contentView sendSubviewToBack: selectedSoundDownAndRight]; 
     } 
     if (soundRow == leftRow && soundRow == downRow && soundRow == rightRow && 
      soundSection == leftSection && soundSection == downSection && soundSection == rightSection){ 
      [selectedSoundLeftAndDown removeFromSuperview]; 
      [selectedSoundLeftAndRight removeFromSuperview]; 
      [selectedSoundDownAndRight removeFromSuperview]; 
      [selectedSoundLeft removeFromSuperview]; 
      [selectedSoundDown removeFromSuperview]; 
      [selectedSoundRight removeFromSuperview]; 
      [cell.contentView addSubview: selectedSoundLeftAndDownAndRight]; 
      selectedSoundLeftAndDownAndRight.frame = CGRectMake(200,8,30,30); 
     } 
     else { 
      [cell.contentView sendSubviewToBack: selectedSoundLeftAndDownAndRight]; 
     } 

    [indexPath retain]; 
    return cell;  
} 

只是想对这篇文章进行更新。我昨天花了12个小时试图解决这个问题,这超出了我目前的技能。我将单元格选择风格设置为无,这很糟糕,但现在是时候投入毛巾了。

我完全抛弃该代码有利于下面的方法,它检查了所有当前可见的指数路径,分配给声音的索引路径的存在,然后除去子视图酌情:

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


/* NSArray *allVisibleCells = [table visibleCells]; 

    leftIsVisible = FALSE; 
    downIsVisible = FALSE; 
    rightIsVisible = FALSE; 

    NSLog(@"\n\n\n", (leftIsVisible ? @"TRUE" : @"FALSE")); 

    NSLog(@"Start: %@\n", (leftIsVisible ? @"TRUE" : @"FALSE")); 


    for (UITableViewCell *visibleCell in allVisibleCells){ 

     NSIndexPath *visibleCellIndexPath = [table indexPathForCell: visibleCell]; 
     NSLog(@"visible cell index path %@\n", visibleCellIndexPath); 

     if ([visibleCellIndexPath compare: leftOldIndexPath] == NSOrderedSame) { 
      leftIsVisible = TRUE; 
      NSLog(@"Compare successful: %@\n", (leftIsVisible ? @"TRUE" : @"FALSE")); 
     } 
     if ([visibleCellIndexPath compare: downOldIndexPath] == NSOrderedSame) { 
      downIsVisible = TRUE; 
     } 
     if ([visibleCellIndexPath compare: rightOldIndexPath] == NSOrderedSame){ 
      rightIsVisible = TRUE; 
     } 
    } 

    NSLog(@"After the first fast enumeration: %@\n", (leftIsVisible ? @"TRUE" : @"FALSE")); 
    NSLog(@"After check for left is still visible %@\n", (leftIsVisible ? @"TRUE" : @"FALSE")); 

    if(leftIsVisible == FALSE){ 
     [selectedSoundLeft removeFromSuperview]; 
     [selectedSoundLeftAndDown removeFromSuperview]; 
     [selectedSoundLeftAndRight removeFromSuperview]; 
     [selectedSoundLeftAndDownAndRight removeFromSuperview]; 
    } 
    if(downIsVisible == FALSE){ 
     [selectedSoundDownAndRight removeFromSuperview]; 
     [selectedSoundDown removeFromSuperview]; 
    } 
    if (rightIsVisible == FALSE){ 
     [selectedSoundRight removeFromSuperview]; 
    } */ 
+0

包括屏幕截图,但325行代码的优点在这种格式中过度且无法阅读。你应该能够将问题缩小到50行以下。即使你不能,你也应该使用PasteBin或类似的服务发布很长的代码。否则,很少有人会麻烦阅读它。 – TechZen 2010-04-02 14:30:37

+0

感谢TechZen - 我将代码范围缩小到问题可能来自哪里。对我而言有趣的是,我只在选定状态期间看到子视图。但是我确信在擦拭板岩时我需要做得更好。 – 2010-04-02 14:41:49

我不没有时间去浏览325行代码,但是最可能导致你的问题的是重用tableview单元格,而没有先清除它们的子视图。

您会看到箭头出现在未指定的单元格中,因为实际的单元格对象将从显示的前几行重新使用。由于您有自定义子视图,因此每次单元格更改信息时都必须手动管理该子视图。

每次你重复使用一个单元格时,你的第一步应该是将它擦干净,直到它的初始状态。只有这样你才能将新数据加载到单元格中。

正确的方式(以及Apple Docs的说法)是在所有子视图上使用标签。如果单元格正在创建(未出队/重用),那么您可以像常规那样创建单元格,但设置了唯一标记(整数,尽管您可以使用define来使其更易于阅读)。如果该单元正在出列/重用,那么您使用标签获取单元格。在Apple Docs中查找自定义UItableViews以及关于自定义tableviewcells的一节。