iOS中的tableView reloadRowsAtIndexPaths方法无法工作

10

我有一个问题,我有一个UITableViewController,当视图出现时,我会异步进行一些计算,这应该导致表格中特定行的更新。

viewWillAppear函数内,我按以下方式计算需要更新的必要行:

- (void)reloadPaths:(NSMutableDictionary *)bookingsDict
{
    NSMutableArray* indexArray = [NSMutableArray array];
    int i = 0;
    for (NSString *dateKey in self.eventsToShow) {
        NSMutableDictionary *venues = [bookingsDict objectForKey:dateKey];
        if (venues) {
            int j = 0;
            NSArray *events = [self.eventsToShow objectForKey:dateKey];
            for (DCTEvent *event in events) {
                NSString *venueIdString = [NSString stringWithFormat:@"%@", event.eventVenueId];
                if ([venues objectForKey:venueIdString]) {
                    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:j inSection:i];
                    [indexArray addObject:indexPath];
                }
                j++;
            }
        }
        i++;
    }
    [self.tableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationFade];
}

然而我注意到cellForRowAtIndexPath函数在此之后从未被调用,导致单元格没有正确更新。不知道问题出在哪里?

编辑:我刚刚注意到,如果我滚动视图使得要更新的单元格不再可见,那么当我重新滚回来时,它就会被更新。有没有办法让它在可见状态下也更新?


你检查过 indexArray 是否包含有效数据了吗? - Argent
这是我在调试器中看到的内容:po indexArray <__NSArrayM 0xd0c3a40>( <NSIndexPath: 0xd0dffa0> {length = 2, path = 15 - 0} ) - Atul Bhatia
我刚刚注意到,如果我滚动一下,那么单元格就会更新。我猜这意味着当前可见的单元格直到你滚动离开它们才会被更新? - Atul Bhatia
不会崩溃,只是在我将单元格滚出视图之前不会更新。 - Atul Bhatia
请查看我的答案,看看它是否能帮到你:https://dev59.com/hnTYa4cB1Zd3GeqPpwVF#41551850 - Michael Westbrooks II
3个回答

10

2
谢谢,它起作用了。我在stackoverflow上读到过,不需要使用begin和end更新。我尝试通过重新加载路径行来解决问题,但并没有起效。但是当我将reloadRowsAtIndexPathsself.tableView.beginUpdates()self.tableView.endUpdates()一起使用时 它很有效。有人能解释一下为什么需要begin和end吗? - kishorer747

5

编辑:我认为你没有理解indexPath检查部分可能是常量,因为每个对象都被遍历时都会增加:

- (void)reloadPaths:(NSMutableDictionary *)bookingsDict
{
    NSMutableArray* indexArray = [NSMutableArray array];
    int i = 0;
    for (NSString *dateKey in self.eventsToShow) {
        NSMutableDictionary *venues = [bookingsDict objectForKey:dateKey];
        if (venues) {
            int j = 0;
            NSArray *events = [self.eventsToShow objectForKey:dateKey];
            for (DCTEvent *event in events) {
                NSString *venueIdString = [NSString stringWithFormat:@"%@", event.eventVenueId];
                if ([venues objectForKey:venueIdString]) {
                    //changed here as section might be constant as i think it might be
                    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:j inSection:0];
                    [indexArray addObject:indexPath];
                }
                j++;
            }
        }
        i++;
    }

    [self.tableView beginUpdates];
    [self.tableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationFade];
    [self.tableView endUpdates];
}

尝试这个:

试试看:

//your code here
[self.tableView beginUpdates];

[self.tableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationFade];

[self.tableView endUpdates];

5
问题仍然存在 - 我必须将单元格滚动出视图才能使其更新。 - Atul Bhatia
@AtulBhatia:检查indexArray是否有任何indexPath? - Paresh Navadiya
不,这部分是可变的。如果我将reloadRowsAtIndexPaths简单地更改为reloadData,它就可以正常工作。 - Atul Bhatia
我认为在reloadRowsAtIndexPaths之后使用reloadData是唯一可行的方法。 - ideawu

3
对于我来说,将我的重新加载代码推送到主队列解决了这个问题。
DispatchQueue.main.async {
    self.tableView.reloadRows(at: [indexPath], with: .automatic)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接