我在我的iPhone应用中使用UITableView,我有一个属于一个组的人的列表。我希望当用户单击一个特定的人(因此选择单元格)时,单元格的高度会增加,以显示用于编辑这个人的属性的几个UI控件。
这可能吗?
我在我的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];
}
}
其他回答
我发现了一个非常简单的解决方案,作为一个UITableView的副作用,我正在.....工作
将单元格高度存储在一个变量中,该变量通常通过tableView: highightforrowatindexpath:来报告原始高度,然后当你想要动画化高度变化时,只需改变变量的值并调用这个…
[tableView beginUpdates];
[tableView endUpdates];
你会发现它不会完全重载,但足以让UITableView知道它必须重绘单元格,为单元格....抓取新的高度值你猜怎么着?它使你的改变变得生动。甜的。
我有一个更详细的解释和完整的代码示例在我的博客…动画UITableView单元格高度变化
只是一个提示,像我这样的人搜索添加“更多细节”自定义单元格。
[tableView beginUpdates];
[tableView endUpdates];
做了一个出色的工作,但不要忘记“裁剪”单元格视图。 从界面构建器中选择单元格->内容视图->从属性检查器中选择“剪辑子视图”
下面是我的自定义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;
}
BOOL flag;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
flag = !flag;
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:@[indexPath]
withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView endUpdates];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES == flag ? 20 : 40;
}
而不是beginUpdates()/ endpdates(),建议调用现在是:
tableView.performBatchUpdates(nil, completion: nil)
关于beginUpdates/ endpdates,苹果说:“尽可能使用performBatchUpdates(_:completion:)方法而不是这个方法。”
参见:https://developer.apple.com/documentation/uikit/uitableview/1614908-beginupdates