[英]cellForRowAtIndexPath: not called
我的應用程序有兩種狀態:登錄和未登錄,我有以下架構(大大簡化):
- 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:
的斷點永遠不會被命中。
為什么會調用numberOfRowsInSection
但不會調用cellForRowAtIndexPath
一種有效情況是當表的大小或位置不需要顯示任何行時。
例如,假設您有一個 20 像素高的表格,但是第一部分的標題是 30 高,並且您為標題返回了 nil(或者沒有實現viewForHeaderInSection
)。 在這種情況下,不會顯示任何行,並且看起來表格不存在。
我看到你在使用 IB。 表格的大小在 IB 中可能具有欺騙性,因為它假設頁眉和頁腳大小。 我會記錄表格的框架,以便您了解應用程序運行時的位置(相對於它出現在 IB 中的位置)。 我還要確保在調用 reloadData之前手動調整表格框架的大小和位置。 這將解決未調用cellForRowAtIndexPath
這種有效情況。
檢查numberOfSectionsInTableView
是否沒有返回 0。
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
我遇到了完全相同的問題,問題是我試圖從另一個線程調用 reloadData: 。 解決方案是:
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
如果您像我一樣使用不同的數據源,請確保保留數據源。 僅僅實例化將成為數據源的類並通過tableView.dataSource = myDataClass
分配它是不夠的,因為 tableView 的 dataSource 屬性很弱,並且會在 viewDidLoad 完成時釋放。 所有其他方法都被我調用了——甚至,令人驚訝的是, heightForRowAtIndexPath
所以這花了我一些時間來調試。
// 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;
如果視圖中的表視圖與 Scrool 視圖之類的內容發生沖突,則不會調用它。 您應該將 Storyboard 或 *.xib 文件中的視圖分開。
// True
▼ View
► Table View
► Scrool View
► Constraints
// False
▼ View
► Scrool View
► Table View
► Constraints
我們有相同/相似的問題。 代碼達到了numberOfSections
和numberOfRowsInSection
(它甚至返回了值)但無法達到cellForRowAt
。 當時,Storyboard 中的 Table View 只有右側、左側和頂部的約束,而沒有底部的約束。 一旦我們在底部添加約束,它就像一個魅力。
因此,請檢查您是否為表視圖提供了所有需要的約束。
每個人都在談論高度,但我在StackView
TableView
以領先對齊結束,寬度為 0。
確保使用Debug View Hierarchy
檢查您的TableView
的大小是否正確。
如果您像我一樣使用自動布局並將 tableview 添加到視圖控制器的視圖中,請確保在分配 table view 時添加了這一行。
tableView?.translatesAutoresizingMaskIntoConstraints = false
我這邊的愚蠢錯誤。
我解決了這個問題,因為我添加了UITableView
子視圖沒有分配,所以它返回 nill 並且 tableview 沒有調用cellForRowAtIndexPath
而是numberOfRowsInSection
被調用
我正在使用客戶數據源,它已發布。 因為它是tableview的弱引用。
這令人尷尬和困惑,但這是我的解決方案。
我的代碼:
_scanResultTable.delegate = self;
_scanResultTable.dataSource = self; // self's lifecycle was fine, wasn't getting released
[_scanResultTable reloadData];
所以奇怪的部分是:標識符 _scanResultTable 從未在我的代碼中聲明,在項目的任何地方。 我不知道這是如何編譯的(我重新編譯了幾次)。
我的根本原因是我已將表輸出鏈接到 ViewController 中的scanResultTable
,但將其稱為 _scanResultTable。 一旦我開始像我應該使用的那樣使用scanResultTable
,事情就清楚了。 這讓我想知道objective-c是否有一些關於標識符中前導下划線的特殊之處......
編輯: 確實如此! 天哪,我迫不及待地不想再碰這種語言了。
浪費了幾個小時,然后發現我的 tableview 在 stackview 中。 一旦我刪除了堆棧視圖,它就像一個魅力。 對我來說是 Xcode 11.3 。
我正在使用 ReactiveCocoa。 所以我為表視圖創建了模型。 數據已准備好顯示,因此numberOfRows
等。 但是我沒有將 tableview 添加為 subview,因此沒有調用cellForRowAtIndexPath
)))
- (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];
}
就我而言,我在StackView
有TableView
。 當我把它放在 StackView 之外時,它起作用了。
嘗試手動插入新行而不是[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;
}
我通過檢查 tableViewCell 標識符解決了同樣的問題。 轉到屬性檢查器並查看標識符部分。 大概是失蹤了。 所以寫單元格標識符。
同樣的情況,但這是一個錯誤:
我在 ViewController 中包含了一個帶有 2 個表視圖的 Scrollview(設計要求),在滾動視圖控制器中我以編程方式創建了 ViewControllers(包含 TableViews),我使用了一個弱變量來存儲它,壞主意,因為它們是在年底發布的viewDidLoad 方法。
如果您沒有看到您的 tableview 內容,請檢查它是否已發布。
我的錯誤對我來說非常痛苦,因為除了 viewForCell 之外,所有方法(委托和數據源)都被調用了......
這里的答案都沒有幫助我。
我正在以編程方式使用我的約束,但忘了寫:
myTableView.translatesAutoresizingMaskIntoConstraints = false
確保您的約束是正確的,並且在構建時沒有刪除任何約束。
這可能太明顯了,但在我的情況下,我正在以編程方式刪除一個元素(標簽),該元素是對表格頂部邊距的引用,因此委托/源不是問題,而是表格的內容存在問題-大小/高度,這個沖突產生了一個奇怪的行為,調用 numberOfRowsInSection 而不是 cellForRowAt indexPath
您確定在用戶登錄並彈出 B 后,會調用 A 中的viewWillAppear
方法以執行刷新嗎?
如果您將 B 顯示為模態控制器,當您關閉它時,您將不會調用viewWillAppear
方法。
據我所知, viewWillAppear/viewDidAppear
(以及其他類似的)是 UINavigationController 在導航事件(push/pop viewcontrollers)的情況下生成的事件。 所以也許這就是為什么當你離開 A 並返回時你最終會刷新......這一切都取決於顯示下一個視圖控制器的方式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.