我在我的iPhone应用中使用UITableView,我有一个属于一个组的人的列表。我希望当用户单击一个特定的人(因此选择单元格)时,单元格的高度会增加,以显示用于编辑这个人的属性的几个UI控件。

这可能吗?


当前回答

添加一个属性来跟踪选定的单元格

@property (nonatomic) int currentSelection;

将它设置为(例如)viewDidLoad中的哨兵值,以确保UITableView从“正常”位置开始

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    //sentinel
    self.currentSelection = -1;
}

在highightforrowatindexpath中,您可以为所选单元格设置所需的高度

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    int rowHeight;
    if ([indexPath row] == self.currentSelection) {
        rowHeight = self.newCellHeight;
    } else rowHeight = 57.0f;
    return rowHeight;
}

在didSelectRowAtIndexPath中,如果需要,保存当前选择并保存动态高度

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        // do things with your cell here

        // set selection
        self.currentSelection = indexPath.row;
        // save height for full text label
        self.newCellHeight = cell.titleLbl.frame.size.height + cell.descriptionLbl.frame.size.height + 10;

        // animate
        [tableView beginUpdates];
        [tableView endUpdates];
    }
}

在didDeselectRowAtIndexPath中将选择索引设置回哨兵值,并将单元格动画回正常形式

- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {       
        // do things with your cell here

        // sentinel
        self.currentSelection = -1;

        // animate
        [tableView beginUpdates];
        [tableView endUpdates];
    }
}

其他回答

我喜欢西蒙·李的回答。我实际上并没有尝试这个方法,但它看起来会改变列表中所有单元格的大小。我只是希望改变一下被窃听的细胞。我有点像西蒙,但有一点不同。这将改变选定单元格时的外观。它确实有动画。只是另一种方法。

创建一个int来保存当前选定单元格索引的值:

int currentSelection;

然后:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    int row = [indexPath row];
    selectedNumber = row;
    [tableView beginUpdates];
    [tableView endUpdates];
}

然后:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    if ([indexPath row] == currentSelection) {
        return  80;
    }
    else return 40;


}

我相信您可以在tableView:cellForRowAtIndexPath:中进行类似的更改,以更改单元格的类型,甚至为单元格加载xib文件。

像这样,currentSelection将从0开始。如果您不希望列表的第一个单元格(在索引0处)默认情况下看起来是选中的,则需要进行调整。

下面是我的自定义UITableView子类的代码,它在表格单元展开UITextView,而无需重新加载(和丢失键盘焦点):

- (void)textViewDidChange:(UITextView *)textView {
    CGFloat textHeight = [textView sizeThatFits:CGSizeMake(self.width, MAXFLOAT)].height;
    // Check, if text height changed
    if (self.previousTextHeight != textHeight && self.previousTextHeight > 0) {
        [self beginUpdates];

        // Calculate difference in height
        CGFloat difference = textHeight - self.previousTextHeight;

        // Update currently editing cell's height
        CGRect editingCellFrame = self.editingCell.frame;
        editingCellFrame.size.height += difference;
        self.editingCell.frame = editingCellFrame;

        // Update UITableView contentSize
        self.contentSize = CGSizeMake(self.contentSize.width, self.contentSize.height + difference);

        // Scroll to bottom if cell is at the end of the table
        if (self.editingNoteInEndOfTable) {
            self.contentOffset = CGPointMake(self.contentOffset.x, self.contentOffset.y + difference);
        } else {
            // Update all next to editing cells
            NSInteger editingCellIndex = [self.visibleCells indexOfObject:self.editingCell];
            for (NSInteger i = editingCellIndex; i < self.visibleCells.count; i++) {
                UITableViewCell *cell = self.visibleCells[i];
                CGRect cellFrame = cell.frame;
                cellFrame.origin.y += difference;
                cell.frame = cellFrame;
            }
        }
        [self endUpdates];
    }
    self.previousTextHeight = textHeight;
}

而不是beginUpdates()/ endpdates(),建议调用现在是:

tableView.performBatchUpdates(nil, completion: nil)

关于beginUpdates/ endpdates,苹果说:“尽可能使用performBatchUpdates(_:completion:)方法而不是这个方法。”

参见:https://developer.apple.com/documentation/uikit/uitableview/1614908-beginupdates

下面是Simons对Swift 3的简短回答。还允许切换单元格的选择

var cellIsSelected: IndexPath?


  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    cellIsSelected = cellIsSelected == indexPath ? nil : indexPath
    tableView.beginUpdates()
    tableView.endUpdates()
  }


  func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if cellIsSelected == indexPath {
      return 250
    }
    return 65
  }

输入- - -

tableView.beginUpdates () tableView.endUpdates () 这些函数不会调用

func tableView(_ tableView: UITableView, cellForRowAt indexPath: indexPath) -> UITableViewCell {}

但是,如果你这样做了, 表视图。reloadRows (:(selectedIndexPath !, .none)

它会调用 func tableView(_ tableView: UITableView, cellForRowAt indexPath: indexPath) -> UITableViewCell {} 这个函数。