現在、iOS6 専用アプリで状態の自動保存/復元を実装しています。
テーブルビューを復元するUIDataSourceModelAssociation
ために、テーブルビューコントローラーにプロトコルを追加して実装しました
- (NSString *)modelIdentifierForElementAtIndexPath:(NSIndexPath *)idx inView:(UIView *)view
と
- (NSIndexPath *)indexPathForElementWithModelIdentifier:(NSString *)identifier inView:(UIView *)view
ホーム ボタンを押すと、 を含む状態保持メソッドmodelIdentifierForElementAtIndexPath:iView:
が期待どおりに呼び出され、指定されたインデックス パスに対して有効な識別子文字列が返されます。
アプリを強制終了して再起動すると、状態の復元は多かれ少なかれ機能します。つまり、アプリは正しいテーブル ビューを再度開きます。ただし、以前に別の位置にスクロールした場合でも、テーブル ビューは常に一番上にスクロールされます。
UIDataSourceModelAssociation
これが、テーブル ビュー コントローラーでのメソッドの実装です。そこには特別なことは何もありません (NdlFriend::accountUid
プロパティは、指定された NdlFriend レコードの一意の識別子文字列を返します):
#pragma mark - UIDataSourceModelAssociation
- (NSString *)modelIdentifierForElementAtIndexPath:(NSIndexPath *)idx inView:(UIView *)view
{
NSString* identifier = nil;
NSArray* content = self.contentArray;
// Sometimes idx might be nil...
if(idx && idx.row<content.count)
{
NdlFriend* friend = content[idx.row];
identifier=friend.accountUid;
}
return identifier;
}
- (NSIndexPath *)indexPathForElementWithModelIdentifier:(NSString *)identifier inView:(UIView *)view
{
NSIndexPath * indexPath=nil;
NSArray* content = self.contentArray;
NSInteger count = content.count;
for(NSInteger i=0;i<count;i++)
{
NdlFriend* friend = content[i];
if([identifier isEqualToString:friend.accountUid])
{
indexPath = [NSIndexPath indexPathForRow:i inSection:0];
break;
}
}
return indexPath;
}
どちらの方法でもブレークポイントを設定します。
メソッドをテストするために、テーブル ビューを開いて少し下にスクロールしました。次に、ホームボタンを押すと:
modelIdentifierForElementAtIndexPath:inView:
一番上に表示されている行のインデックス パスを使用して、1 回呼び出されます。このメソッドは、この行の正しい uid を返します。
ここまでは順調ですね。
次に、アプリを停止して再起動します。何が起こるかは次のとおりです (特に、最初のヒット ブレーク ポイントに困惑しています)。
modelIdentifierForElementAtIndexPath:inView:
インデックス パスとして呼び出さnil
れます (ビュー引数には、テーブル ビューの正しいポインターが含まれます)。indexPathForElementWithModelIdentifier:inView:
有効な識別子文字列で呼び出されます (メソッドによって有効なインデックス パスが返されます)。indexPathForElementWithModelIdentifier:inView:
(同じ識別子文字列で) 再度呼び出されます。- テーブル ビューは更新されますが、一番上までスクロールされます。
スクロール位置の復元が失敗する理由を誰かが知っていますか? modelIdentifierForElementAtIndexPath:inView:
with nil
indexPath の呼び出しが何か関係があるのかもしれません (または、これは通常の動作です) 。