ユーザーがいずれかの行のボタンをタップすると、その行の基になるモデルが更新され、指定された行のreloadRowsAtIndexPathsが呼び出されます(つまり、単一行の再読み込み)。
- (IBAction)handleCompleteTouchEvent:(UIButton *)sender {
NSIndexPath *indexPath = [self.tableView indexPathForView:sender];
id item = [self dataForIndexPath:indexPath];
if ([item respondsToSelector:@selector(completed)]) {
// toogle completed value
BOOL completed = ![[item valueForKey:@"completed"] boolValue];
[item setValue:[NSNumber numberWithBool:completed] forKey:@"completed"];
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
}
}
問題は、この呼び出しを行った後、テーブルビューがセクションの上部に跳ね返ることです。これが発生するのを防ぎ、スクロール位置をそのままにするにはどうすればよいですか?
あはは!私は問題を発見し、将来この問題に遭遇する貧しい魂に対する私自身の質問に答えます。
すべてのセルの高さが可変であるため、UITableViewDelegateで新しいiOS7メソッドを使用していたため、レンダリング時間が短縮されるのではないかと考えていました(本当に必要だったわけではありません)。
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath;
とにかく、このメソッドを実装すると、次の呼び出し時にテーブルがセクションの先頭に跳ね返るという悪影響があります。
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
バウンス問題を解決するために、私は見積もられたHeightForRowAtIndexPathメソッドのオーバーライドを削除しただけで、すべてが正常に機能します。やっと幸せ。
これは私にとってはトリックでした。
UIView.setAnimationsEnabled(false)
tableView.reloadRows(at: [...], with: .none)
UIView.setAnimationsEnabled(true)
セルの内容を直接変更することで、実行しようとしていることを実行できるはずです。たとえば、ベースUITableViewCell
クラスを使用していて、モデルのデータがNSString
であり、テーブルビューのセルに表示されている場合、次のことができます(データを変更した後モデル)reloadRowsAtIndexPaths
を呼び出す代わりに:
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
UILabel *label = [cell textLabel];
label.text = @"New Value";
UITableViewCellのカスタムサブクラスを使用している場合、セルのビューへのアクセスはcontentViewプロパティを介して行う必要があることを除いて、ほぼ同じです。
Swift 4.2
これは、アニメーションを削除したい場所であればどこでも機能します。テーブル、テーブルセクション、または任意の行の再読み込み中
UIView.performWithoutAnimation({
cell.configureSelection(isSelected: true)
tableView.reloadSections([1], with: .none)
tableView.allowsSelection = false
})
セルを独自のセクションに配置し、reloadセクションを呼び出すことができる場合があります。
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:UITableViewRowAnimationFade];
これにより、問題が部分的に修正されたようです。きれいな方法ではありませんが、あなたのために働くかもしれません。
私の同様のケースでは、メソッドの実装を微調整する必要がありました
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
...
}
私の身長がリセットされていた場所。したがって、すべてのセルの高さをリセットするのではなく、reloadRowsAtIndexPaths呼び出しの影響を受けるセルのみを更新しました。
同じ問題がありました。データ/セルを更新した後、代わりにtableView.reloadData()を呼び出すだけで終了しましたが、先頭に戻りませんでした/データが適切に更新されました-FYI
Xseeの答えを基にするには-インターフェイスビルダーでEstimate
を「自動」に設定しました。これを別の番号に変更すると、機能し始めました。 Row Height
自動に。
セルの最小の高さがわかっている場合は、estimatedRowHeight
を設定するときにその高さを指定する必要があります。以前にどこかで読んだように、私はそれを1に設定していましたが、0を超える値は目的を十分に満たしますが、それは原因です。
セルの最小高さである44に設定すると、すべて正常に動作しました。
動的な高さも問題なく機能し、この修正に関する問題はありません。