简体   繁体   English

最后一行删除后如何重新加载自定义表格视图单元格?

[英]How to reload custom table view cell after last row deletion?

I have a UITableView with a simple array as data source. 我有一个带有简单数组作为数据源的UITableView I designed a custom nib for a special UITableViewCell that is shown when the array is empty (ie when the app first starts). 我为特殊的UITableViewCell设计了一个自定义笔尖,该UITableViewCell在数组为空(即应用程序首次启动时)时显示。

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if ([self.wallet count] == 0)
        return 1;
    else return [self.wallet count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // If there isn't any coupon yet, then show the custom "No Coupon Yet" cell
    if ([self.wallet count] == 0)
        return [tableView dequeueReusableCellWithIdentifier:@"NoCouponCell" forIndexPath:indexPath];
    else {
        CouponCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CouponCell" forIndexPath:indexPath];
        Coupon *coupon = [self.wallet objectAtIndex:indexPath.row];

        [cell configureForCoupon:coupon];
        return cell;
    }
}

Since I'd like to add the swipe-to-delete functionality, I provided the following method for the view controller. 由于我想添加滑动删除功能,因此我为视图控制器提供了以下方法。

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    [self.wallet removeObjectAtIndex:indexPath.row];
    // Creates a new, temporary array holding just the one index-path item
    NSMutableArray *tmp = [[NSMutableArray alloc] initWithObjects:indexPath, nil];
    // Tells the table view to delete the row with a nice animation
    [tableView deleteRowsAtIndexPaths:tmp withRowAnimation:UITableViewRowAnimationAutomatic];
}

However, when the table view has only one row and I try to delete it, my app crashes. 但是,当表视图只有一行并且我尝试删除它时,我的应用程序崩溃了。 Why? 为什么?

EDIT: The debug info tells that a NSInternalInconsistencyException is raised. 编辑:调试信息告诉您引发了NSInternalInconsistencyException

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

    if (editingStyle == UITableViewCellEditingStyleDelete) 
    {
        // Delete the row from the data source
        [self.wallet removeObjectAtIndex:indexPath.row];

        [tableView reloadData]; // reload your table to see updates

        // or if you what some animation use|

        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath] 
                         withRowAnimation:UITableViewRowAnimationAutomatic];  

... ...


Here's a fix for your cellForRowAtIndexPath : 这是您的cellForRowAtIndexPath的修复程序:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    CouponCell *cell = [tableView dequeueReusableCellWithIdentifier:[self.wallet count] == 0 ? @"NoCouponCell" : @"CouponCell" forIndexPath:indexPath];

    if ([self.wallet count] > 0)
    {
        Coupon *coupon = [self.wallet objectAtIndex:indexPath.row];

        [cell configureForCoupon:coupon];
    }
    return cell;
}

try this in your code: 在您的代码中尝试以下操作:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return [self.wallet count];
}

Use this in your numberOfRowsInSection function: 在您的numberOfRowsInSection函数中使用此函数:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

      return [self.wallet count];
}

And at the end of your commitEditingStyle function, use 然后在commitEditingStyle函数的末尾使用

[tableView reloadData]; 

Try this piece of code: 尝试这段代码:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    [self.wallet removeObjectAtIndex:indexPath.row];
    // Creates a new, temporary array holding just the one index-path item
    NSMutableArray *tmp = [[NSMutableArray alloc] initWithObjects:indexPath, nil];
    // Tells the table view to delete the row with a nice animation
    [tableView beginUpdates];
    [tableView deleteRowsAtIndexPaths:tmp withRowAnimation:UITableViewRowAnimationAutomatic];
    [tableView endUpdates];
}

You are returning a rowcount of 1 if your data array wallet has no elements: 如果数据数组wallet没有元素,则返回的行数为1:

 if ([self.wallet count] == 0)
        return 1;
    else return [self.wallet count];

But in the commitEditingStyle method you don't handle this case: This means that it's possible to delete the NoCouponCell . 但是在commitEditingStyle方法中,您无法处理这种情况:这意味着可以删除NoCouponCell And I assume that the crash occurs, because you want to remove an object from your data-array which does not exist. 而且我认为发生崩溃是因为您要从数据数组中删除一个不存在的对象。

[self.wallet removeObjectAtIndex:indexPath.row];

Solution : Use the following delegate method to determine when a cell can be edited: This prevents the delegate method commitEditingStyle to be called. 解决方案 :使用以下委托方法来确定何时可以编辑单元格:这可以防止调用委​​托方法commitEditingStyle

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
    return [self.wallet count] > 0
}

you can add a view to the UITableview tableFooterView on tableview datasource, you can put your custome cell'content in this view 您可以在tableview数据源上的UITableview tableFooterView中添加视图,可以在此视图中放置客户单元格的内容

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    if (dataArray.count == 0) {
        UIView *view = [[UITableView alloc] initWithFrame:self.view.bounds];
        view.backgroundColor = [UIColor blueColor];
        self.tableView.tableFooterView = view;
    }
    return dataArray.count;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM