我目前正在仅 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:
被调用一次,带有最顶部可见行的索引路径。该方法返回此行的正确 uid。
到目前为止,一切都很好。
然后我停止并重新启动应用程序。这是发生的事情(我对第一个命中断点特别困惑):
modelIdentifierForElementAtIndexPath:inView:
被调用,nil
作为索引路径(视图参数包含表视图的正确指针)。indexPathForElementWithModelIdentifier:inView:
使用有效的标识符字符串调用(并且该方法返回有效的索引路径)。indexPathForElementWithModelIdentifier:inView:
再次被调用(使用相同的标识符字符串)。- 表格视图已刷新,但滚动到最顶部。
有人知道,为什么滚动位置的恢复失败?modelIdentifierForElementAtIndexPath:inView:
with nil
as indexPath的调用是否与它有关(或者这是正常行为)。