【问题标题】:Hiding UITableViewCell隐藏 UITableViewCell
【发布时间】:2010-04-19 20:32:34
【问题描述】:

有没有办法隐藏 UITableView 单元格?我正在寻找一些可以在同步 cellForRowAtIndexPath() 返回的 UITableViewCell 上调用的属性或方法,以隐藏它并使其无法被用户选择。

【问题讨论】:

    标签: iphone cocoa-touch


    【解决方案1】:

    对我来说使用映射并不容易,所以我决定使用 SAS 方法。但它不适用于我的自定义单元格。所以,我纠正它:

    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if(indexPath.row == 7 && hide7Row){
            UITableViewCell* cell = [cells objectAtIndex:indexPath.row];
            cell.hidden = YES;
            return 0.0;
        }
        else if(indexPath.row == 8 && hide8Row){
            UITableViewCell* cell = [cells objectAtIndex:indexPath.row];
            cell.hidden = YES;
            return 0.0;
        }
        else {
            return 44.0;
        }
    }
    

    工作正常。

    【讨论】:

    • 那么 cells 是一个数组,其中包含 tableview 每一行的 UITableViewCell?那很糟。 UITable 模式用于在单元格离开屏幕时将其放入重用队列中。所以很有可能你最终会隐藏错误的单元格。我根本看不到您的代码是如何工作的,除非在特殊情况下表格太短以至于没有单元格滚动到屏幕外。或者您只尝试隐藏屏幕上的单元格的另一种特殊情况。不推荐。
    • @SteveWaddicor 你是对的,存储单元格是一种不好的做法。我们可以存储作为隐藏单元掩码的布尔数字数组,并在调用 cellForRowatIndexPath 方法时设置它
    【解决方案2】:

    您的意思是在单元格应该在的表格中留出一个空隙,或者只是从它之前的那个直接前进到它之后的那个?在前一种情况下,我想您可能会尝试获取单元格的 contentView 并将其 hidden 属性设置为 YES;否则,您只需在 -tableView:numberOfRowsInSection:-tableView:cellForRowAtIndexPath: 方法中执行一些逻辑,从第一个返回(否则返回的单元格数 - 1),并且取决于行索引是否为分别小于或大于您不包括的行(您将返回的单元格)或(位于(行索引 + 1)处的单元格)。

    (编辑,因为解释很复杂:)

    - (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
    {
        if(section == theSectionWithoutARow)
        {
            if(shouldRemoveTheRow)
                return [theArrayWithTheSectionContents count] - 1;
            else
                return [theArrayWithTheSectionContents count];
        }
        // other sections, whatever
    }
    
    - (UITableViewCell *)tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        // blah blah standard table cell creation
    
        id theCellObject;
    
        if(indexPath.section == theSectionWithoutARow)
        {
            NSInteger theActualRowToDisplay = indexPath.row;
            if(shouldRemoveTheRow && indexPath.row >= theRowIndexToRemove)
            {
                theActualRowToDisplay = indexPath.row + 1;
            }
            theCellObject = [theArrayWithTheSectionContents objectAtIndex:theActualRowToDisplay];
        }
    
        // now set up the cell with theCellObject
    
        return cell;
    }
    

    【讨论】:

    • @andsien numberOfRowsInSection 和 cellForRowAtIndexPath 方法在节中作为参数传递。您的表格可能有多个部分,这两种方法将在表格中的 any 部分调用。所以 Noah 的代码确保方法调用是针对正确的部分。显然这是伪代码,所以他编造了一个节指针并将其命名为“theSectionWithoutARow”,因为它很好而且具有描述性。
    • 你如何将它应用到具有静态单元格的 UITableView 定义例如作为故事板的一部分。大概您必须覆盖 UITableViewDataSource 中定义的一些/所有方法以适当地减少节号和索引路径。这里有人试过吗?
    【解决方案3】:

    据我所知,在 cellForRowAtIndexPath 上没有方法可以做到这一点。

    Noah Witherspoon 的方法似乎或多或少可行,但如果您想隐藏多行,则需要对其进行修改。

    另一种方法是创建“单元格图”,我不知道这是否更有效,但我已经使用它并且它有效。

    假设您有一个 NSArray(或其可变版本)的数据要显示在您的 TableView 中。数组的 count 属性用作 numberOfRowsInSection 委托方法的返回值。据我所知,这是一种比较典型的方法。

    为了只显示一些行,我创建了一个“映射数组”,它是一个 NSMutableArray,其中包含指向您的实际数据数组的“指针”。该映射包含包裹在 NSNumbers 中的整数。在原始状态下,地图的索引 0 具有整数 0(包裹在 NSNumber 中),索引 1 具有整数 1,等等。

    UITableView 委托方法的构建是为了将地图的索引计数用于 numberOfRowsInSection。在 cellForRowAtIndexPath 方法中,它查看映射数组的适当索引,检索包裹在 NSNumber 中的任何内容,然后查看实际数据数组的 那个索引。

    这种取消引用的好处是在表格中添加和删除单元格变得非常容易。只需从映射数组中添加/删除 NSNumber 对象。有道理?抱歉,不在我的 Mac 上,或者我可以放一些代码示例。

    哦,别忘了您必须在 TableView 上调用 update 方法(确切的名称让我无法理解),以便它刷新并且单元格隐藏/取消隐藏。

    【讨论】:

      【解决方案4】:

      遇到了同样的问题,因为我想避免前面提到的一些映射,所以我只是将单元格大小设置为 0:

      - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
      
          NSInteger row=[indexPath row];
          float ret=0.0;
      
          if( row==3) {
              ret=0.0;
          }
          else {
              ret=40.0;
          }
          return ret;
      }
      

      【讨论】:

        【解决方案5】:

        我使用 Matt 的技术来创建到单元格数据的映射。这是一些代码:

        - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
            return computeNumberOfRowsAndMapCellData;
        }
        
        // Compute mapToCellData to map the index of the cell to the cell data for the 
        // cell based on TaskConfig show/hide.
        // Return the number of rows in section 1.
        - (NSInteger)computeNumberOfRowsAndMapCellData {
            if (mapToCellData) {
                [mapToCellData release];
            }
            mapToCellData =[[NSMutableArray alloc] init];
            if (cellData) {
                [cellData release];
            }
            cellData = [[NSMutableArray alloc] init];
        
            NSInteger numberOfRows = 12;  // maximum number of rows
            NSNumber *index = [NSNumber numberWithInt:0];
        
            // If the data is not configured to show, decrement the number of rows in the table. 
            if ( ! [configManager isShowDateForType:task.case_type severity:task.severity]) {
                numberOfRows--;
            } else {
                // Add a map to the cell data with the row number.
                NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[df stringFromDate:task.respond_due_date], @"Respond Due", nil];
                [cellData addObject:dict];
                [mapToCellData addObject:index];
                int value = [index intValue];
                index = [NSNumber numberWithInt:value + 1];
            }
            // Check the configuration for the rest of the rows of cell data.
            ....
        }
        
        - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];        
            if (cell == nil) {
                cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
                cell.textLabel.numberOfLines = 0;
                cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
                cell.textLabel.font = [UIFont fontWithName:@"Helvetica-Bold" size:15];
                cell.detailTextLabel.font = [UIFont fontWithName:@"Helvetica-Bold" size:14];
            }
        
            NSUInteger mapIndex = 0;
        
            // Use the mapToCellData to find cell data based on show/hide in ConfigManager for the data type.
            mapIndex = [indexPath row];
            NSNumber *cellDataIndex = [mapToCellData objectAtIndex:mapIndex];
            NSDictionary *cellDataDict = [cellData objectAtIndex:[cellDataIndex unsignedIntegerValue]]; 
            cell.textLabel.text = = [[cellDataDict allValues] objectAtIndex:0];
            cell.detailTextLabel.text = [[cellDataDict allKeys] objectAtIndex:0];
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-03-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多