UITableView行已删除但未隐藏

时间:2013-08-08 19:28:47

标签: ios uitableview

我是一个可滑动的tableView单元格,在单元格中有一个删除该行的按钮。我在我的方法中有这个代码来删除行。从DataSource中正确删除了行的内容,但是我在隐藏和重新加载tableView时遇到了麻烦。这是我的代码:

- (void)deleteElementAtIndexPath:(NSIndexPath *)indexPath {
    [dateTableView beginUpdates];

    NSUserDefaults *user = [NSUserDefaults standardUserDefaults];

    listTitles = [[NSMutableArray alloc] init];

    listTitles = [[user objectForKey:@"listTitles"] mutableCopy];

    [listTitles removeObjectAtIndex:indexPath.row];

    [user setObject:listTitles forKey:@"listTitles"];
    [user synchronize];

    [dateTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
    [dateTableView endUpdates];
    [dateTableView reloadData];
}

我的类有delegate和dataSource协议。这也是我的委托方法:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    NSLog(@"reloading...numberofsection");
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSLog(@"reloading...numberofrowsinsection");

    return [listTitles count];
}

3 个答案:

答案 0 :(得分:2)

一些事情:

- (void)deleteElementAtIndexPath:(NSIndexPath *)indexPath {

    // [dateTableView beginUpdates]; This shouldn't be placed here

    NSLog(@"This method was called: %@", NSStringFromSelector(_cmd)); // Check if this method is even called       

    // NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; don't bother creating a new object

    // listTitles = [[NSMutableArray alloc] init]; Since you are reinitialising down below this is not needed

    // listTitles = [[user objectForKey:@"listTitles"] mutableCopy]; Don't bother creating a new object

    [[[[NSUserDefaults standardUserDefaults] objectForKey:@"listTitles"] mutableCopy] removeObjectAtIndex:indexPath.row];
    [[NSUserDefaults standardUserDefaults] synchronize];

    [dateTableView beginUpdates];
    [dateTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
    [dateTableView endUpdates];

    // Now try this - THIS IS THE MOST IMPORTANT CHANGE: calling -setNeedsDisplay**
    [dateTableView reloadData];
    [dateTableView setNeedsDisplay];
}

其他一些事情:

  

我的类有delegate和dataSource协议。这也是我的委托方法:

-numberOfSectionsInTableView:-numberOfRowsInSection:都是数据源方法,请确保您已实施其他必修项-cellForRowAtIndexPath:,您的委托方法类似于-commitEditingStyle::和{{ 1}}

Also this is a good open source cell swiping project

答案 1 :(得分:1)

取出这些内容 -

listTitles = [[NSMutableArray alloc] init];

listTitles = [[user objectForKey:@"listTitles"] mutableCopy];

[dateTableView reloadData];

然后绝对完全确保您的IBOulets已连接。我看到您正在使用名为dateTableView的tableView实例,该实例表明您正在使用自定义UIViewController类。如果您使用Interface Builder,则必须确保已将Outlet连接到表。如果没有,在某处调用dateTableView就像向nil发送消息一样。

答案 2 :(得分:0)

当你在下一行覆盖变量时,NSMutableArray的分配是无用的。如果调用beginUpdates和endUpdates,也不需要reloadData。

确保您作为参数传递的indexPath具有正确的Section,也许tableview尝试删除错误部分的行。如果该部分是正确的,您应该检查您的UITableViewDataSource的实现。

验证

listTitles = [[user objectForKey:@"listTitles"] mutableCopy];

不会返回NIL。否则,您在此对象上调用的每个新方法都将无效。您还应该从numberOfRowsInSection:中记录返回的单元格数。顺便说一句,更清洁的实施将是:

@property (strong, nonatomic) NSMutableArray * listTitles;
@synthesize listTitles;

- (void)deleteElementAtIndexPath:(NSIndexPath *)indexPath {
    [dateTableView beginUpdates];

    [self.listTitles removeObjectAtIndex:indexPath.row];

    NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
    [user setObject:self.listTitles forKey:@"listTitles"];
    [user synchronize];

    [dateTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
    [dateTableView endUpdates];
}

在构造函数(或控制器的viewDidLoad)中,执行以下操作

self.listTitles = [[[NSUserDefaults standardUserDefaults] objectForKey:@"listTitles"] mutableCopy];
if (self.listTitles == nil) {
    self.listTitles = [[NSMutableArray alloc] init];
}