0

10000 個以上のセルを持つテーブル ビューがあります。上部にセグメント ボタン (すべて/お気に入り) があります。

これはセグメントのコールバックです:

- (IBAction)call_segment:(id)sender {

    [self.tableView beginUpdates];
    [self.tableView reloadData];
    [self.tableView endUpdates];
}

お気に入りのページは、お気に入りの項目がない場合でも、セルの高さを 0 に設定するだけです。しかし、このようにして、画面上に 10000 個以上のセルをすべて作成しました。

「すべて」が選択されている場合、セルは通常の高さを持ち、それらの一部のみが画面上でキューから取り出されるため、テーブルは正常に機能します。

これが私のコードです:

//お気に入りにない場合は、高さを 0 に設定して非表示にします

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    if ([self isFavorite]) {
        int uniqueId = [self uniqueIdWithIndexPath:indexPath];
        if ([DATABASE isFavoriteWithMode:self.mode uniqueId:uniqueId] == NO) {
            return 0;
        }
    }
    return 60;
}

//テーブル ビュー データソース: //問題は、高さを 0 に設定すると、すべてのセルが割り当てられることだと思います。セルを非表示に設定しましたが、それでもメモリが必要です。それに対処する方法はありますか?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    BOOL isFavorite = [DATABASE isFavoriteWithMode:self.mode uniqueId:[self uniqueIdWithIndexPath:indexPath]];

    if ([self isFavorite] && isFavorite == NO) {
        cell.hidden = YES;
        return [[UITableViewCell alloc] init];

    }
    else {
        cell.hidden = NO;
        ListCell *cell = (ListCell *)[tableView dequeueReusableCellWithIdentifier:CELL_LIST];

        Datum *datum = [DATABASE datumWithMode:self.mode uniqueId:[self uniqueIdWithIndexPath:indexPath]];


        BOOL isRead = [DATABASE isReadWithMode:self.mode uniqueId:[self uniqueIdWithIndexPath:indexPath]];


        cell.indexLabel.text = [NSString stringWithFormat:@"%d", datum.uniqueId];
        cell.titleLabel.text = [NSString stringWithFormat:@"%@", datum.q];


        return cell;
    }

}

注: ロジックが複雑すぎるため、お気に入りのセルだけを表示したくありません。私は sqlite を使用していますが、「すべて」タブが正常に機能するため、データベースのパフォーマンスが問題になるとは思いません。

高さを0に設定したかった理由は、セル番号の単純な実装です

- (BOOL)isFavorite {
    return self.segment.selectedSegmentIndex == 1;
}


- (IBAction)call_segment:(id)sender {

    [self.tableView beginUpdates];
    [self.tableView reloadData];
    [self.tableView endUpdates];
}

#define NUM_SECTIONS 15

- (int)numRows {
    return [DATABASE numberOfDataForModes:self.mode];
}

- (int)numSections {
    if ([self numRows] % NUM_SECTIONS > 0) {
        int numSections = [self numRows] / [self numRowsPerSection];
        if ([self numRows] % [self numRowsPerSection] > 0) {
            numSections++;
        }
        return numSections;
    }
    return NUM_SECTIONS;
}

- (int)numRowsPerSection {
    return [self numRows] / NUM_SECTIONS;
}

- (int)numRowsInLastSection {
    if ([self numRows] % ([self numSections] - 1) > 0) {
        return [self numRows] % ([self numSections] - 1);
    }
    else {
        return [self numRowsPerSection];
    }
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    int start = section * [self numRowsPerSection] + 1;
    int end = start + [self numRowsPerSection] - 1;
    if (end > [self numRows]) {
        end = [self numRows];
    }
    return [NSString stringWithFormat:@"From %d to %d", start, end];
}

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
    NSMutableArray *titles = [NSMutableArray arrayWithCapacity:[self numSections]];
    int start = 1;
    while (start < [self numRows]) {

        NSString *title = [NSString stringWithFormat:@"%d", start];
        [titles addObject:title];

        start += [self numRowsPerSection];
    }

    return titles;

}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
    return index;
}

- (int)uniqueIdWithIndexPath:(NSIndexPath *)indexPath {
    int uniqueId = indexPath.row + 1 + indexPath.section * [self numRowsPerSection];
    return uniqueId;
}

- (NSIndexPath *)indexPathWithUniqueId: (int)uniqueId {
    int section = (uniqueId - 1) / [self numRowsPerSection];
    int row = uniqueId - 1 - [self numRowsPerSection] * section;

    return [NSIndexPath indexPathForRow:row inSection:section];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    if ([self isFavorite]) {
        int uniqueId = [self uniqueIdWithIndexPath:indexPath];
        if ([DATABASE isFavoriteWithMode:self.mode uniqueId:uniqueId] == NO) {
            return 0;
        }
    }
    return 60;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (section == [self numSections] - 1) {
        return [self numRowsInLastSection];
    }
    return [self numRowsPerSection];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return [self numSections];
}
4

4 に答える 4

4

セルを非表示にする代わりに、データソース メソッドから 0 を返すだけではどうですか

 – tableView:numberOfRowsInSection: 

この関数内で isFavorite 値を利用し、NO の場合は 0 を返すことができます。

于 2013-06-07T08:35:18.570 に答える
3

あなたはすでにそれを手に入れました。問題は、お気に入りでないセルの 0 のサイズです。これは、細胞の再利用という考えに反します。画面には何千ものセルが表示されますが、表示されていませんが、存在しているためリソースを消費します。もっとスマートな方法を考えたほうがいいです。データ ソース デリゲート (私が推測するビュー コントローラー) は、お気に入りでないセルの数のみを返す必要があるため、cellForRowAtIndexPathお気に入りでないアイテムのセルのみを提供する必要があります。さらにcellForRowAtIndexPath、コード スニペットに表示されないセルを実際に再利用する必要があります。

于 2013-06-07T08:40:00.897 に答える
1

画面に 10,000 回のビューを表示しようとしても、問題の解決にはなりません。tableView:numberOfRowsInSection:[お気に入り] タブが選択されたときにデリゲートに対して 0 を返すことができるように、コード構造を変更する必要があります。

他の「解決策」は、代替案を一緒にハックしようとする試みですが、これは機能せず、いずれにせよ悪いコード プラクティスです。デリゲートに適切に応答して、適切に実装します。

于 2013-06-07T09:00:28.153 に答える
0

両方のテーブルセクションを分離することをあきらめました。ロジックが複雑すぎる。

セルを非表示にしてもメモリを節約する方法はないと思います。ご意見をお寄せいただきありがとうございます。あなたはすべて正しいです。

通常、お気に入りのテーブルはそれほど長くないため、実際にはそれほど悪くはありません。すべてのエントリを含む 1 つのセクションのみ。

于 2013-06-10T01:53:43.040 に答える