簡體   English   中英

為什么有時在numberOfRowsInSection之前調用heightForRowAtIndexPath?

[英]Why sometime heightForRowAtIndexPath is called before numberOfRowsInSection?

我有這個代碼

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    UnlockTableSectionHeaderType type = (UnlockTableSectionHeaderType) [self.sections[section] integerValue];
    switch (type) {
        case UnlockTableSectionTypeAllLeaderBoard:
            return 1;
        case UnlockTableSectionTypeTopic:
            NSLog(@"%@", [self.topicController showLoading] ? @"YES" : @"NO");
            NSLog(@"%d", [self.topicController loadedItemCount]);
            return [self.topicController showLoading] ? 1 : [self.topicController loadedItemCount];
        case UnlockTableSectionTypeCategory:
            return [self.categoryController showLoading] ? 1 : [self.categoryController loadedItemCount];
        default:
            return 0;
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return [UnlockTableSectionHeaderView defautHeight];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    UnlockTableSectionHeaderType type = (UnlockTableSectionHeaderType) [self.sections[indexPath.section] integerValue];
    NSInteger row = indexPath.row;

    switch (type) {
        case UnlockTableSectionTypeAllLeaderBoard:
            return 207.0f;
        case UnlockTableSectionTypeTopic:
            NSLog(@"heightForRow %@", [self.topicController showLoading] ? @"YES" : @"NO");
            NSLog(@"heightForRow %d", [self.topicController loadedItemCount]);
            return [self.topicController showLoading] ? 130.0f :
                    [TopicCell heightForTopicCellForThread:[self.topicController itemForIndex:row] showCategory:YES];
        case UnlockTableSectionTypeCategory:
            return 120.0f;
    }
    return 0.0f;
}

嘗試使用控制器顯示數據( Controller就像負責從Web和領域查詢數據的Controller一樣)

這是我得到的日志

Sent message: 41|{"id":51,"m":"group.getAllUnlock","p":[{"limit":15,"skip":0}]} <-- call to server
Sent message: 41|{"id":52,"m":"thread.queryUnlock","p":[{"limit":15,"skip":0}]} <-- call to server
YES
0
heightForRow YES
heightForRow 0
YES
0
heightForRow YES
heightForRow 0
YES
0
heightForRow YES
heightForRow 0
YES
0
heightForRow YES
heightForRow 0
heightForRow YES
heightForRow 0
heightForRow YES
heightForRow 0
YES
0
heightForRow YES
heightForRow 0
YES
0
heightForRow YES
heightForRow 0
Got response for RPC call 52, 34 bytes <-- response from server
Zip size: 838
Got response for RPC call 51, 3087 bytes <-- response from server
heightForRow NO <-- Height For Row called first
heightForRow 0
WARNING: GoogleAnalytics 3.10 void GAIUncaughtExceptionHandler(NSException *) (GAIUncaughtExceptionHandler.m:49): Uncaught exception: Index 0 is out of bounds (must be less than 0)

如您所見,當我從服務器獲取數據時,我會在領域中更新結果,並使用領域通知對該方法進行委托調用

- (void)controllerDidReloadData:(BaseController *_Nonnull)controller {
    [self.tableView reloadData];
}

但是不知怎么不調用numberOfRowsInSection ...

它在此行崩潰

return [self.topicController showLoading] ? 130.0f :
                    [TopicCell heightForTopicCellForThread:[self.topicController itemForIndex:row] showCategory:YES];

我該如何解決? 謝謝

更新

現在查看一下stacktrace,很抱歉不及早包含它,我現在不能這樣做,因為我們已經更改了設計。 通過刪除主題並僅保留類別,現在我們只有一種類型的控制器,並且崩潰也消失了……似乎這是每個節有兩種類型的數據源的問題,而其中一種是更新的,而另一種是仍然更新它會導致崩潰。

無論如何,有關更多信息,正在從cellForRowAtIndexPath這一行調用heightForRowAtIndexPath

if (type == UnlockTableSectionTypeTopic) {
        if ([self.topicController showLoading]) {
            return [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([LoadingTableViewCell class]) forIndexPath:indexPath];
        }
        // Below line is the line which called `heightForRowAtIndexPath` when looking into the stacktrace
        TopicCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([TopicCell class]) forIndexPath:indexPath];
        cell.delegate = self;
        [cell configureCellForThread:[self.topicController itemForIndex:row]
                            lastCell:row == [self.topicController loadedItemCount] - 1
                        showCategory:YES];
        return cell;
    }

但我不知道為什么此時要調用cellForRowAtIndexPath

heightForRowAtIndexPath:cellForRowAtIndexPath:方法可以隨時調用,例如在滾動過程中。 當表視圖知道基礎數據已更改時,將僅調用numberOfRowsInSection: 這就是reloadData調用的目的:告訴表視圖數據已更改,並且需要重新初始化表。

因此,重要的是更新主線程上的基礎數據(在您的情況下為Realm),並在此之后立即調用reloadData

您的[self.topicController showLoading]似乎是一種避免這樣做的解決方法。 可以很好地工作,但是隨后您需要確保更改showLoading狀態並直接在主線程上彼此直接調用reloadData

這是由蘋果定義的。 但是,當您考慮時-這很有意義。 如果它們占據了整個屏幕的高度,則詢問另一部分的行數是沒有意義的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM