CoreDataのTableViewでのmoveRowAtIndexPathの謎


CoreDataに連動したTableViewのアプリの場合、おなじみのfetchedResultsControllerの書いて、各レコードにはソート番号を入れるdisplayOrderというNSNumberの項目を作って表示順を管理している。
まず、第一の謎。ソート番号って必要なのか?

fetchedResultsControllerを用いないのであれば、ソートのためのdisplayOrderは作らずに、物理的な行の入れ替えだけを行えばいいようなのだが、CoreDataの場合、レコード生成した順番が必ずしも物理的な順番とは限らないので、やはりソート番号による管理は必須のようだ。

第二の謎。moveRowAtIndexPathに来た時点では、indexPathの順番は既に変わっているのだろうか。それとも、まだ変わっていないのか?つまり僕は、moveRowAtIndexPathはどこからどこへの移動するか教えてくれるが、TableView上での移動自体はこちらの仕事かもしれないと思ったわけである。

サンプルコードを読むと、TableView上では順番は既に変わっていると考えてよいようだ。ということはTableViewは編集済みと考えて、この編集結果に基づいてCoreData上のソート番号をリナンバーするだけでよい。

さていよいよ、ではmoveRowAtIndexPath で入れ替えたレコードのソート番号をどのように再編集すべきか。ググって出てくる下記のようないくつものサンプルコードある。
iphone – Rearranging UITableView with Core Data – Stack Overflow
Reordering rows in a UITableView with Core Data
Re-Ordering NSFetchedResultsController
How can I maintain display order in UITableView using Core Data?
やはりレコード全部のソート番号をリナンバするのではなく移動元の行から移動先の行までのレコードだけ調べてソート番号の番号を振り直しているのがかっこいい。

僕としては、一番下のものがしっくりくる。移動元と移動先のソート番号をスワップして、それ以外のものを一個ずつずらすという論理がわかりやすいからだ。

しかし、これらを見て第四の謎が生じる。
みんな新規レコードのセルはテーブルの先頭に追加しているのだろうか、それとも末尾に追加か?普通は先頭に追加ではないかと思う。そして同時に、レコード生成時にソート番号をどうやって生成しているのだろう。新しいレコードのソート番号を全ソート番号の最大値+1にするのではないかな。だとすればソート順は降順になる。

なのに上記のググったサンプルはことごとく昇順を基本にしている。不安である。ソート番号の生成方法が僕の場合間違っているかも。どうするのがいいか、わからないままとりあえず降順管理をすることにした。

その点で、一番下のサンプル例の場合、1)スワップする値はtoIndexそのものではないので工夫が必要ということと、2)設定しているdelta値のプラスマイナス値を逆にすればいいだけなので、そういう意味でもこのサンプルが気に入っている。

1)については以下のようにした。

FFObject *affectedObject = nil;
affectedObject = [self.fetchedResultsController.fetchedObjects objectAtIndex:toIndex];
NSNumber* toOrder = affectedObject.displayOrderValue;
affectedObject = [self.fetchedResultsController.fetchedObjects objectAtIndex:fromIndex];
affectedObject.displayOrderValue = toOrder;

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中