web-dev-qa-db-ja.com

テーブルビューのリロードセクションのクラッシュ

4つのセクションとセクションごとに1〜2個のテーブルビューセルがあるテーブルビューがあります。最初のセルには、アクセサリビューとしてuiswitchがあり、アプリのカラーテーマを制御して、デイモードとナイトモードを切り替えます。スイッチを押すと関数が呼び出され、ナビゲーションバーの色と背景色が変更されます。その関数には、私も行を入れました

[self.tableview reloadData];

テーブル自体を新しい色で更新します。正常に動作しますが、アニメーションがないため、代わりにこれを使用しました

[self.tableView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 3)] withRowAnimation:UITableViewRowAnimationFade];

その回線を使用すると、スイッチが動かなくなり、アプリがフリーズします。言うまでもなくクラッシュすることはありません。つまり、クラッシュログはなく、フリーズするだけで、アニメーションの途中でuiswitchが停止します。

アクセサリビューを含むセルがないセクションをリロードでき、フェードアニメーションで完全に機能することに気付きました。つまりこれは動作します

[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:2] withRowAnimation:UITableViewRowAnimationFade];

3番目のセクションには、アクセサリビューのセルがないためです。しかし、アクセサリビューを含むセルがあるセクション(つまり、セクション0と2)をリロードしようとすると、アプリがフリーズします。

なぜこれが起こっているのか考えはありますか?以下は私のcellForRowAtIndexPathです

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *cellIdentifier;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier];

if (indexPath.section == 0) {

    cell.textLabel.text = [section0 objectAtIndex:indexPath.row];
    cell.accessoryType = UITableViewCellAccessoryNone;
    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    if (indexPath.row == 0) {

        cell.accessoryView = colorSchemeSwitch;
    }

    else if (indexPath.row == 1) {

        cell.accessoryView = autoLockSwitch;
    }
}

else if (indexPath.section == 1) {

    cell.textLabel.text = [section1 objectAtIndex:indexPath.row];
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}

else if (indexPath.section == 2) {

    cell.textLabel.text = [section2 objectAtIndex:indexPath.row];
    cell.accessoryType = UITableViewCellAccessoryNone;
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    cell.detailTextLabel.text = [NSString stringWithFormat:@"%i \t", (int)app.fontSize];
    fontSizeSlider.value = app.fontSize;
    cell.accessoryView = fontSizeSlider;
}

else if (indexPath.section == 3) {

    cell.textLabel.text = [section3 objectAtIndex:indexPath.row];
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    cell.detailTextLabel.text = app.color;
}

cell.backgroundColor = app.cellBackgroundColor;
cell.textLabel.textColor = app.textColor;
UIView *backgroundColorView = [[UIView alloc] init];
backgroundColorView.backgroundColor = app.cellSelectedColor;
[cell setSelectedBackgroundView:backgroundColorView];

return cell;
}
8
jcooper_82

UITableViewCellで構成されるUISwitchでも同じ問題が発生しました。セクションをリロードする前に[self.tableview reloadData]を呼び出すことで、問題を解決しました。

NSIndexSet *sections = [[NSIndexSet alloc] initWithIndex:2];
[self.tableView reloadData];
[self.tableView reloadSections:sections withRowAnimation:UITableViewRowAnimationFade];

次の電話をかけると、同じ問題が発生します。

[self.tableView reloadRowsAtIndexPaths:[self.tableView indexPathsForVisibleRows] withRowAnimation:UITableViewRowAnimationFade]

最初にデータをリロードせずに。

7
pjuzeliunas

クラッシュログを追加していませんが、セクション内の既存の行数が更新前の値と等しくなければならないというエラーが発生していると推測しています。その場合、テーブルをリロードする前に[self.tableview beginUpdates]を使用し、リロード後に[self.tableview endUpdates]を使用しましたか?

4
Frantzdy Romain