对modelIdentifierForElementAtIndexPath的异常调用:inView:(UIDataSourceModelAssociation)

Zag*_*ggo 8 ios ios6

我目前正在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;
}
Run Code Online (Sandbox Code Playgroud)

我在两种方法中都设置了断点.

为了测试方法,我打开了表视图并向下滚动了一下.然后,当按下主页按钮时:

  • modelIdentifierForElementAtIndexPath:inView:使用最顶部可见行的索引路径调用一次.该方法返回此行的正确uid.

到现在为止还挺好.

然后我停下来重新启动应用程序.这是发生的事情(我对第一个命中断点感到特别困惑):

  • modelIdentifierForElementAtIndexPath:inView:使用nil索引路径调用(视图参数包含表视图的正确指针).
  • indexPathForElementWithModelIdentifier:inView: 使用有效的标识符字符串调用(并且方法返回有效的索引路径).
  • indexPathForElementWithModelIdentifier:inView: 再次调用(使用相同的标识符字符串).
  • 表视图已刷新,但滚动到最顶层.

有人知道,为什么滚动位置的恢复失败了?也许modelIdentifierForElementAtIndexPath:inView:使用nilas作为indexPath 的调用与它有关(或者这是正常的行为).

Aky*_*Aky 1

我认为您遇到的表视图滚动位置重置问题与 UIDataSourceModelAssociation 方法无关。

我相信导航控制器中嵌入的表视图控制器存在一个错误,导致它在恢复后重置其滚动位置。据我了解,如果表视图中的单元格不重新排序,则不需要实现 UIDataSourceModelAssociation 方法,并且应该“免费”获得滚动位置(即只要您选择状态保存并设置修复体 ID)。我无法从文档中明确确认这一点,除了指出 UITableView 继承自 UIScrollView,后者保存了其滚动位置。我已经测试过,如果您将表视图控制器设置为根控制器,或者将表视图控制器嵌入到选项卡栏控制器中,则滚动位置恢复。

我已经提交了错误报告,如果您还没有的话,您也应该提交。