UITableViewCellの挿入と削除が同時に機能しない
-
22-07-2019 - |
質問
同じUITableViewからUITableViewCellsを挿入および削除するのにかなり苦労しています!
通常はコードを投稿しませんが、これが私が問題を抱えている場所を示す最良の方法だと思いました:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 5;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (iSelectedSection == section) return 5;
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//NSLog(@"drawing row:%d section:%d", [indexPath row], [indexPath section]);
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
if (iSelectedSection == [indexPath section]) {
cell.textColor = [UIColor redColor];
} else {
cell.textColor = [UIColor blackColor];
}
cell.text = [NSString stringWithFormat:@"Section: %d Row: %d", [indexPath section], [indexPath row]];
// Set up the cell
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic -- create and push a new view controller
if ([indexPath row] == 0) {
NSMutableArray *rowsToRemove = [NSMutableArray array];
NSMutableArray *rowsToAdd = [NSMutableArray array];
for(int i=0; i<5; i++) {
//NSLog(@"Adding row:%d section:%d ", i, [indexPath section]);
//NSLog(@"Removing row:%d section:%d ", i, iSelectedSection);
[rowsToAdd addObject:[NSIndexPath indexPathForRow:i inSection:[indexPath section]]];
[rowsToRemove addObject:[NSIndexPath indexPathForRow:i inSection:iSelectedSection]];
}
iSelectedSection = [indexPath section];
[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:rowsToRemove withRowAnimation:YES];
[tableView insertRowsAtIndexPaths:rowsToAdd withRowAnimation:YES];
[tableView endUpdates];
}
}
このコードは5つのセクションを作成します。最初のセクション(0からインデックス付け)は5行です。セクションを選択すると、以前に選択したセクションから行が削除され、選択したセクションに行が追加されます。
概念的に、アプリをロードすると、次のようなものになります:
画像: http://www.freeimagehosting.net/uploads/1b9f2d57e7.png
セクション2のテーブル行0を選択した後、セクション1の行(デフォルトで選択されている)を削除し、セクション2の行を追加します。しかし、次のようになります。
画像: http://www.freeimagehosting.net/uploads/6d5d904e84.png
...これは私が期待するものではありません!セクション2の最初の行は何らかの形で残っているようです-たとえ完全に削除されたとしても。
[tableView reloadData]を実行するだけで、すべてが正常に表示されます...しかし、私は明らかに素敵なアニメーションを提供します。
誰かがここで光を放つことができたら本当に感謝しています!それは私を少し狂わせています!
ありがとうございます、 ニック。
解決 5
FYI:このバグは、iPhone 2.2のアップデートで完全に修正されたようです。 アップルありがとう! ニック。
他のヒント
これを機能させるのに苦労しました。 tableViewに行を追加するコードは次のとおりです。
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[tableView beginUpdates];
[dataSource insertObject:[artistField text] atIndex:0];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];
[tableView endUpdates];
deleteRowsまたはinsertRowを呼び出すとnumberOfRowsInSection:が呼び出されることを覚えているようです。実際のnumberOfRowsInSection cliamsが変更と一致するように注意する必要があります。この場合、iSelectedSection = [indexPath section];を移動してみてください。 endUpdatesの後の行。
これをどこで読んだか覚えていませんが、テーブルビューのデリゲート関数の1つからテーブル行の更新(挿入および削除)を実行しないでください。オブジェクトとして更新を実行するために必要な情報を渡すperformSelectorOnMainThreadを実行するのがより良い代替手段だと思います。次のようなもの:
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// ....
[self performSelectorOnMainThread: @selector(insertRows:)
withObject: someObjectOrNil]; // double check args
}
- (void) insertRows: (NSObject*)someObjectOrNil {
[tableView beginUpdates];
// update logic
[tableView endUpdates];
// don't call reloadData here, but ensure that data returned from the
// table view delegate functions are in sync
}
投稿したコードでは、ループインデックスは0から4まで実行されます。これは、セクション1の行のすべてを削除し、セクション2に5つの新しい行を追加することを示唆しています。各セクションにはすでに行0があります。これにより、セクション2、行0の second インスタンスがテーブルに追加されます。
ループを1〜4で実行することをお勧めします。
for (int i=1; i<5; i++)
{
// ...
}