簡體   English   中英

為什么我的 UITableView 在異步重新加載數據期間滾動時會失去流動性?

[英]Why does my UITableView lose it's fluidity when I scroll during an asynchronous reload data?

這是我的問題...我正在對我正在使用的服務進行異步調用,它將搜索結果返回給我。 完成后,它會重新加載我的表,並且異步完成。 問題是,當我在異步調用完成之前嘗試滾動表格視圖時,表格會失去所有滾動視圖所具有的流暢感。 我的意思是,當您讓 go 滾動時,而不是繼續前進並緩慢停止,只要您讓 go 停止,它就會停止。 恢復流暢感的唯一方法就是一直滾動到UITableView的頂部或底部再往前一點,就可以了。

這是我的異步調用代碼:

__block NSMutableArray *appendMoreObjects = [[NSMutableArray alloc] init];

    dispatch_async( dispatch_get_main_queue(), ^{

        self.activity.hidden = NO;

        appendMoreObjects = [service search:self.query from:((moreCount * 8)) until:((moreCount * 8) + 8)];

        if( appendMoreObjects == nil )
        {
            //alert view
        }
        else
        {
            [self.allSearchResults addObjectsFromArray:appendMoreObjects];

            [self updateSearchArray];

            self.moreCount += 1;
        }

        self.activity.hidden = YES;
    });

另外,請記住,我使用的是自定義 UITableViewCell。 如果需要任何其他信息,請提出要求,我會看看我能做些什么。 先感謝您。

EDIT1:[self updateSearchArray] 包含 [tableView reloadData]

EDIT2:我正在運行 4.3.1 (8G4) 的 iPod Touch 上進行測試

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
customCell * cell = (customCell *)[tableView dequeueReusableCellWithIdentifier:@"cell"];

if( cell == nil )
{
    cell = [[[customCell alloc] initWithFrame:CGRectZero] autorelease];
}

if( indexPath.row == [self.searchResults count] && [self.searchResults count] > 0)
{

    UITableViewCell *moreCell = [[[UITableViewCell alloc] initWithFrame:CGRectZero] autorelease];
    moreCell.textLabel.text = @"More";
    moreCell.textLabel.textAlignment = UITextAlignmentCenter;

    return moreCell;
}

if( indexPath.row < [self.searchResults count] )
{
    [cell formatAndInsertData:[self.searchResults objectAtIndex:indexPath.row]];
}

return cell;
}

解決方案:

我實際上最終做的是鎖定表格和所有 UI 元素,直到調用完成。 也許不是最好的解決方案,但它仍然有效。

調用[tableView reloadData]將重新加載您的整個表,這就是您看到不穩定的 UITableView 的原因。 它強制所有可見單元格刷新,因此當您滾動時,可見單元格正在刷新並重新繪制自己。 您需要重新評估更新 UITableView 的策略,因為您有數據進入以避免這種情況。 您應該更新可能可見的具有與您的更新相關的數據的單個單元格。

為此,您將需要使用以下方法:

– insertRowsAtIndexPaths:withRowAnimation:

– deleteRowsAtIndexPaths:withRowAnimation:

– reloadRowsAtIndexPaths:withRowAnimation:

這些組合將允許您在接收數據時更新表(添加/刪除行),而不是強制刷新整個表。

我想查看自定義單元格,以充分回答您的問題。

此外,表格 controller 的 cellForRowAtIndexPath: 段,以查看您如何重用單元格。

最后但同樣重要的是:您正在測試哪種類型的設備? (類型和世代)

編輯:

這部分:

if( indexPath.row == [self.searchResults count] && [self.searchResults count] > 0)
{

    UITableViewCell *moreCell = [[[UITableViewCell alloc] initWithFrame:CGRectZero] autorelease];
    moreCell.textLabel.text = @"More";
    moreCell.textLabel.textAlignment = UITextAlignmentCenter;

    return moreCell;
}

看起來完全有毒......現在沒有時間測試它,但請不要在單元格中添加單元格......表格控制器不僅會混淆,而且會阻止太多memory。

僅將 cellForRowAtIndexPath: 用於簡單的事情,例如填寫標題、描述和圖像。

在 tableview controller 上執行重新加載邏輯,但在更安全的地方。 每次出現單元格時都會加載 cellForRowAtIndexPath,即使它剛剛出現。

確保您只在主線程上重新加載表數據。 最好,我使用 nsinvocation 而不是 GCD :)

暫無
暫無

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

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