0

1000個を超えるセルを含むテーブルビューがあります(画面に約10個表示されます)。ユーザーによる「フィルター」アクションに続いて、それらの約80%を削除し、2番目のフィルターの後にさらに80%を削除します。100個のセルを操作する場合はほぼ瞬時ですが、1000個の場合はメソッド[tableView endUpdates]を完了するのに0.5秒かかり、これによりユーザーエクスペリエンスが完全に破壊されます。

次のようにインデックスパスの配列を作成します。

for (int i=1; i<[appDelegate.myArray count]; i++) {   //more than 1000 objects in myArray
    if (![[appDelegate.myArray objectAtIndex:i] myTest]) {  //myTest returns a BOOL 
        [appDelegate.rowsToDelete addObject:[NSIndexPath xxxxx]]; //the index path of the object that just failed the test and must be removed];
 }
}
[self.myTableViewController.tableView deleteRowsAtIndexPaths:appDelegate.rowsToDelete withRowAnimation:UITableViewRowAnimationRight];

私は2つの解決策を試しました。1つはスレッド化で、tableViewが更新されているときにUIの他の部分が移動しているのをユーザーが確認できるようにします。しかし、彼が別のレベルのフィルタリングを開始した場合、これはクラッシュではないにしても、多くの場合、長い待機になります。

また、最初のいくつかのセル(画面上のセル)を削除してから、テストに失敗した他のオブジェクトをデータソースから削除しようとしましたが、対応するセルは見えないため、tableViewから削除しませんでした。これにより、良好で迅速な結果が得られますが、次のような行数の問題が発生します。

'無効な更新:セクション0の無効な行数。更新後の既存のセクションに含まれる行数(94)は、更新前のそのセクションに含まれる行数(927)に、プラスマイナスそのセクションから挿入または削除された行の数(0が挿入され、215が削除されました)。

誰かがそのようなパフォーマンスの問題を抱えていましたか?それを解決する方法は?乾杯、CD

4

3 に答える 3

0

プロパティをキャッシュし、ループに高速列挙を使用してみてください。

//int i = 0;
NSMutableArray *rowsToDelete = appDelegate.rowsToDelete;
for(id current in appDelegate.myArray) {
    if([current myTest]) [rowsToDelete addObject:[NSIndexPath ...]];
    //++i;
}
[self.myTableViewController.tableView deleteRowsAtIndexPaths:rowsToDelete withRowAnimation:UITableViewRowAnimationRight];

アイテムのインデックスを使用してNSIndexPathを作成する場合は、1行目と5行目のコメントを解除します。また、コードではi=1から開始していることに気づきました。NSArrayは0から始まるため、最初のセルが削除されることはありません。実際にこれが必要な場合は、i=0をi=1に変更します。

于 2010-12-15T21:37:25.867 に答える
0

フィルタリングを実行し、代わりに新しい行数を使用してテーブルビュー全体をリロードすることもできます。とにかく見えなくなってしまった場合、これらすべての削除アニメーションを実行しても意味がありません。または、どの部分が表示されているかを把握してから、現在ユーザーに表示されている行のみを読み込んで削除しますか?

于 2011-02-01T13:49:59.673 に答える
0

ビューを操作するのではなく、dataSourceをリロードする必要があるという@futureelite7に同意します。私はここで同様の質問に対する解決策を提案しました。

基本的な考え方は、reloadSections:withRowAnimation:を呼び出し、UITableViewDataSourceメソッドでセグメント化されたコントロールのselectedSegmentIndexをオンにすることです。

データがフラット(1つのセクションのみ)であると仮定すると、次のようになります。

- (IBAction)segmentSwitch:(id)sender
{
    [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    switch (self.segmentedControl.selectedSegmentIndex)
    {
        default:
        case 0:
            return [self.allRows count];
        case 1:
            return [self.onlySomeRows count];
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    id data;
    switch (self.segmentedControl.selectedSegmentIndex)
    {
        default:
        case 0:
            data = [self.allRows objectAtIndex:[indexPath row]];
            break;
        case 1:
            data = [self.onlySomeRows objectAtIndex:[indexPath row]];
            break;
    }

    //TODO: use data to populate and return a UITableViewCell...
}
于 2012-08-03T22:26:18.083 に答える