UITableView,替换选择时的单元格视图

时间:2013-01-31 15:25:27

标签: ios cocoa-touch uitableview

是否可以替换所选单元格的单元格视图?我已将我的控制器注册为数据源和委托。对单元格视图,行号,选择状态等的请求都很好。在单元格选择回调中,我试图让表格视图用新视图重新加载单元格(而不是实际数据!)。基本上,我希望单元格视图能够展开并显示更多基础数据(如果已选中)。问题是我不知道如何使表视图向我的控制器询问新视图。我可以看到视图正在请求单元格高度,但仅此而已。

在视图上调用reloadData可以正常工作,但它效率低下并且带有一系列自己的问题(动画可能性,维护选择状态等)。

2 个答案:

答案 0 :(得分:14)

这是我采取的方法。

@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

class SelectingTableViewController:UITableViewController
    {     内部var selectedIndexPath:NSIndexPath? = nil

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)

        }

}

答案 1 :(得分:2)

你试过了吗?

- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation

然后,您只能指定更新的单元格以进行重新加载。您还可以在重新加载时告诉您的tableview记住或忘记选择状态:

tableViewController.clearsSelectionOnViewWillAppear = NO;

然后你还必须处理

中的自定义视图
- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath