是否可以替换所选单元格的单元格视图?我已将我的控制器注册为数据源和委托。对单元格视图、行号、选择状态等的请求都很好。在单元格选择回调中,我试图让表格视图使用新视图(不是实际数据!)重新加载单元格。基本上,我希望单元格视图展开并显示更多的基础数据,如果它被选中的话。问题是我不知道如何让表格视图向我的控制器询问新视图。我可以看到视图正在请求单元格高度,但仅此而已。
在视图上调用 reloadData 是可行的,但它效率低下,并且会带来一系列问题(动画可能性、维护选择状态等)。
是否可以替换所选单元格的单元格视图?我已将我的控制器注册为数据源和委托。对单元格视图、行号、选择状态等的请求都很好。在单元格选择回调中,我试图让表格视图使用新视图(不是实际数据!)重新加载单元格。基本上,我希望单元格视图展开并显示更多的基础数据,如果它被选中的话。问题是我不知道如何让表格视图向我的控制器询问新视图。我可以看到视图正在请求单元格高度,但仅此而已。
在视图上调用 reloadData 是可行的,但它效率低下,并且会带来一系列问题(动画可能性、维护选择状态等)。
这是我将采取的方法。
@property (nonatomic, strong) NSIndexPath *selectedIndexPath;
将 NSIndexPath 类型的属性设置为您的控制器以存储选择的索引路径。
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.selectedIndexPath = indexPath;
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation: UITableViewRowAnimationNone];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([indexPath compare:self.selectedIndexPath] == NSOrderedSame) {
// Create your custom cell here and return it.
}
else {
// Should create a normal cell and return it.
}
}
确切地。另请注意,您可能想要取消选择。这是 Swift 中的完整代码。根据需要在 cellForRowAtIndexPath 中使用 selectedIndexPath。
// 选择 TableViewController 导入 UIKit
类 SelectingTableViewController: UITableViewController
{ 内部变量 selectedIndexPath:NSIndexPath? = 无
override func viewDidLoad()
{
super.viewDidLoad()
tableView.estimatedRowHeight = 68.0
tableView.rowHeight = UITableViewAutomaticDimension
self.clearsSelectionOnViewWillAppear = false;
}
override func tableView
(tableView:UITableView, didSelectRowAtIndexPath indexPath:NSIndexPath)
{
print("did select....")
// in fact, was this very row selected,
// and the user is clicking to deselect it...
// if you don't want "click a selected row to deselect"
// then on't include this clause.
if selectedIndexPath == indexPath
{
print("(user clicked on selected to deselect)")
selectedIndexPath = nil
tableView.reloadRowsAtIndexPaths(
[indexPath],
withRowAnimation:UITableViewRowAnimation.None)
tableView.deselectRowAtIndexPath(indexPath, animated:false)
return
}
// in fact, was some other row selected??
// user is changing to this row? if so, also deselect that row
if selectedIndexPath != nil
{
let pleaseRedrawMe = selectedIndexPath!
// (note that it will be drawn un-selected
// since we're chaging the 'selectedIndexPath' global)
selectedIndexPath = indexPath
tableView.reloadRowsAtIndexPaths(
[pleaseRedrawMe, indexPath],
withRowAnimation:UITableViewRowAnimation.None)
return;
}
// no previous selection.
// simply select that new one the user just touched.
// note that you can not use Apple's willDeselectRowAtIndexPath
// functions ... because they are freaky
selectedIndexPath = indexPath
tableView.reloadRowsAtIndexPaths(
[indexPath],
withRowAnimation:UITableViewRowAnimation.None)
}
}
你有没有尝试过:
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
然后,您可以只指定更新的单元格进行重新加载。您还可以告诉您的 tableview 在重新加载时记住或忘记选择状态:
tableViewController.clearsSelectionOnViewWillAppear = NO;
然后你还必须处理里面的自定义视图
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath