cellForRowAtIndexPath:未调用

时间:2011-10-10 11:52:48

标签: iphone ios uitableview

我的应用程序有两种状态:登录但未登录,我有以下架构(大大简化):
- ViewController A,包含搜索框和表格视图 - ViewController B,用于登录应用程序。

流程如下:
- 用户未登录;
- A被推入堆栈。在viewWillAppear中,我检查用户是否已登录,如果是,则表示正在进行异步网络请求,一旦完成,表格将加载来自网络的数据。但是,由于此时用户未登录,因此表视图为空;
- 用户点击搜索框;因为他没有登录,B被推(确认后);
- 他在B中成功登录,然后按下弹出B的按钮并再次显示A;
- 此时,因为他已登录,从viewWillAppear我执行异步请求;
- 完成后,我在表格视图上调用reloadData

我注意到numberOfRowsInSection:被调用并返回正确的结果,但之后不调用cellForRowAtIndexPath:并且表保持为空。

我已经检查过并在主线程上调用了reloadData

知道它能是什么吗?因为它让我疯了!

谢谢,
S上。

编辑:这是A中viewWillAppear的代码的异步位。

if ([User isLoggedIn]) {
    [self.asyncRequest fetchDataWithCompletionHandler:^(id response, NSError *error) {
        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
        if (error) {
            [Utils displayError:error];
        } else {
            self.array = response;

            self.isLoaded = YES;
            [self.tableView reloadData];
            [self.tableView setContentOffset:CGPointMake(0.0f, 0.0f) animated:NO];
        }
    }];
}

我已检查异步请求是否成功完成,response包含正确的数据(这是用于支持UITableView的数组)。

reloadData之后,我在tableView:numberOfRowsInSection:中放置了一个断点,它在那里停止并返回array中正确数量的元素。然而,在此之后,tableView:cellForRowAtIndexPath:中的断点永远不会被击中。

23 个答案:

答案 0 :(得分:241)

为什么numberOfRowsInSection将被调用但cellForRowAtIndexPath不会被调用的一个有效方案是当表的大小或位置不需要显示任何行时。

例如,假设你有一个20像素高的表,但是第一部分的标题是30高,你为标题返回nil(或者没有实现viewForHeaderInSection)。在这种情况下,不会显示任何行,看起来就像表格不存在一样。

我看到你正在使用IB。表中的大小可以在IB中具有欺骗性,因为它假设页眉和页脚大小。我会记录表的框架,以便您了解应用程序运行时的位置(与IB中出现的位置相比)。我还要确保在调用reloadData之前手动调整表格框架的大小和位置。这将解决未调用cellForRowAtIndexPath的有效情况。

答案 1 :(得分:39)

检查numberOfSectionsInTableView是否未返回0。

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return 1;
}

答案 2 :(得分:22)

我有完全相同的问题,问题是我试图从另一个线程调用reloadData:解决方案是:

dispatch_async(dispatch_get_main_queue(), ^{
    [self.tableView reloadData];
});

答案 3 :(得分:12)

// For others showing up on this questions via Google, etc.
// Check and make sure you've set the table view's data source and delegate.
self.tableView.dataSource = self;
self.tableView.delegate = self;

答案 4 :(得分:8)

如果视图中的表视图与Scrollview之类的内容发生冲突,则不会调用它。您应该在Storyboard或* .xib文件中分隔视图。

// True
    ▼ View
        ► Table View
        ► Scrool View
        ► Constraints

// False
    ▼ View
        ► Scrool View
            ► Table View
        ► Constraints

答案 5 :(得分:4)

我们有相同/相似的问题。该代码到达了numberOfSectionsnumberOfRowsInSection(甚至返回了值),但无法达到cellForRowAt。当时,情节提要中的“表视图”仅对右侧,左侧和顶部具有约束,而对底部没有约束。将约束添加到底部后,它就像一种魅力。

因此,请检查是否为表视图提供了所有必需的约束。

答案 6 :(得分:3)

每个人都在谈论身高,但TableViewStackView的领先对齐最终为0宽度。

请务必使用TableView检查Debug View Hierarchy的尺寸是否正确。

答案 7 :(得分:2)

我解决了这个问题,因为我添加了UITableView的子视图没有被分配,因此返回nill而tableview没有调用cellForRowAtIndexPathnumberOfRowsInSection被调用

答案 8 :(得分:2)

这令人尴尬和困惑,但这是我的修复。

我的代码:

_scanResultTable.delegate = self;
_scanResultTable.dataSource = self; // self's lifecycle was fine, wasn't getting released
[_scanResultTable reloadData];

所以奇怪的部分是:标识符_scanResultTable从未在我的代码中声明,在项目的任何地方。我不知道这是如何编译的(我多次重新编译)。

我的根本原因是我在ViewController中将表输出链接到scanResultTable,但是将其称为_scanResultTable。一旦我开始使用scanResultTable就像我应该的那样,事情就会消失。这让我想知道objective-c是否有关于标识符中引导下划线的特殊内容......

修改:It does!好主我迫不及待地想再也不接触这种语言了。

答案 9 :(得分:1)

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Make sure self.data isn't nil!
    // If it is, you'll always return 0 and therefore
    // cellForRowAtIndexPath will never get called.
    return [self.data count]; 
}

答案 10 :(得分:1)

我正在使用ReactiveCocoa。所以我为表视图创建了模型。准备好显示数据,因此调用numberOfRows等。但我没有将tableview添加为子视图,因此cellForRowAtIndexPath未被调用)))

答案 11 :(得分:1)

我正在使用客户数据源并已发布。因为它是tableview的弱引用。

答案 12 :(得分:1)

就我而言,我将TableView放在了StackView中。当我将其放在StackView之外时,它可以工作。

答案 13 :(得分:0)

您是否确定在用户登录并弹出B后,A中的viewWillAppear方法会被调用以执行刷新?

如果您将B显示为模态控制器,当您将其关闭时,您将不会调用viewWillAppear方法。

据我所知,viewWillAppear/viewDidAppear(和其他类似的)是UINavigationController在导航事件(push / pop viewcontrollers)的情况下生成的事件。 所以也许这就是你离开A并返回时最终获得刷新的原因...这一切都取决于显示下一个viewcontroller的方式。

答案 14 :(得分:0)

浪费了几个小时,然后发现我的表视图在堆栈视图中。一旦我删除了stackview,它就像一个魅力。对我来说是Xcode 11.3。

答案 15 :(得分:0)

这也许太明显了,但是在我的情况下,我正在以编程方式删除一个元素(Label),该元素是对我的表的上边距的引用,因此这与委托/源无关,但该表存在一些问题内容大小/高度,此冲突创建了一个怪异的行为,调用numberOfRowsInSection但未调用cellForRowAt indexPath

答案 16 :(得分:0)

请确保您的约束正确无误,并且在构建时不会删除任何约束。

答案 17 :(得分:0)

如果您正在使用像我这样的自动布局,并将tableview添加到视图控制器的视图中,请确保在分配表视图时已添加此行。

tableView?.translatesAutoresizingMaskIntoConstraints = false

我这边的愚蠢错误。

答案 18 :(得分:0)

这里的答案都没有帮助我。

我正在以编程方式使用我的约束,但忘了写:

myTableView.translatesAutoresizingMaskIntoConstraints = false

答案 19 :(得分:0)

我有同样的问题 我在StackView和表视图中使用Table View滚动禁用并设置高度约束但在此之后

tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell

无法正常停止调用此方法,Data SourceDelegate设置正确。

如果您遇到与解决方案相同的问题,请将表视图设置为底部,前导,尾随约束

enter image description here

答案 20 :(得分:0)

此处的情况相同,但这是一个错误:

我在ViewController(设计要求)中包含了一个带有2个tablesViews的Scrollview,在滚动视图控制器中,我以编程方式创建了ViewControllers(包含TableViews),并使用弱var 来存储它, 糟糕的主意因为它们是在viewDidLoad方法结束时发布的。

如果您没有看到您的tableview内容,请检查它是否已发布。

我的错误对我来说非常痛苦,因为所有方法(委托和数据源)都被调用,除了viewForCell ......

答案 21 :(得分:0)

我通过检查tableViewCell标识符解决了同样的问题。转到属性İnspector并查看标识符部分。可能缺少。所以写单元标识符。

答案 22 :(得分:0)

尝试手动插入新行而不是[self.tableView reloadData]

[self.tableView beginUpdates];
    for (int i = 0; i < responseArray.count; i++) {
        _rowsNumber += 1;
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
        [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationBottom];
    }
[self.tableView endUpdates];

在dataSource方法中,返回递增int _rowsNumber

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return _rowsNumber;
}