ios – UINavigationController状态恢复(无故事板)

ios – UINavigationController状态恢复(无故事板),第1张

概述我一直在忙于国家恢复.在下面的代码中,UITableViewController的滚动位置被恢复,但是,如果我要进入细节视图(将MyViewController的一个实例推送到导航堆栈),当应用程序重新启动时,它总是返回到第一个视图控制器在导航堆栈(即MyTableViewController)中.有人能够帮助我恢复正确的视图控制器(即MyOtherViewController)吗? AppDel 我一直在忙于国家恢复.在下面的代码中,UItableVIEwController的滚动位置被恢复,但是,如果我要进入细节视图(将MyVIEwController的一个实例推送到导航堆栈),当应用程序重新启动时,它总是返回到第一个视图控制器在导航堆栈(即MytableVIEwController)中.有人能够帮助我恢复正确的视图控制器(即MyOtherVIEwController)吗?

AppDelegate.m

- (BOol)launchWithOptions:(NSDictionary *)launchOptions{    static dispatch_once_t oncetoken;    dispatch_once(&oncetoken,^{        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];        // OverrIDe point for customization after application launch.        MytableVIEwController *table = [[MytableVIEwController alloc] initWithStyle:UItableVIEwStylePlain];        table.depth = 0;        UINavigationController *navCon = [[UINavigationController alloc] initWithRootVIEwController:table];        navCon.restorationIDentifIEr = @"navigationController";        self.window.rootVIEwController = navCon;        self.window.backgroundcolor = [UIcolor whitecolor];        [self.window makeKeyAndVisible];    });    return YES;}- (BOol)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions{    return [self launchWithOptions:launchOptions];}- (BOol)application:(UIApplication *)application dIDFinishLaunchingWithOptions:(NSDictionary *)launchOptions{    return [self launchWithOptions:launchOptions];}

MytableVIEwController.m

- (ID)initWithStyle:(UItableVIEwStyle)style{    self = [super initWithStyle:style];    if(self)    {        self.restorationIDentifIEr = @"master";    }    return self;}- (voID)vIEwDIDLoad{    [super vIEwDIDLoad];    self.Title = @"Master";    self.tableVIEw.restorationIDentifIEr = @"masterVIEw";}#pragma mark - table vIEw data source- (NSInteger)numberOfSectionsIntableVIEw:(UItableVIEw *)tableVIEw{    return 5;}- (NSInteger)tableVIEw:(UItableVIEw *)tableVIEw numberOfRowsInSection:(NSInteger)section{    return 10;}- (Nsstring *)tableVIEw:(UItableVIEw *)tableVIEw TitleForheaderInSection:(NSInteger)section{    return [Nsstring stringWithFormat:@"Section %d",section];}- (UItableVIEwCell *)tableVIEw:(UItableVIEw *)tableVIEw cellForRowAtIndexPath:(NSIndexPath *)indexPath{    static Nsstring *CellIDentifIEr = @"Cell";    UItableVIEwCell *cell = [tableVIEw dequeueReusableCellWithIDentifIEr:CellIDentifIEr];    if(!cell)    {        cell = [[UItableVIEwCell alloc] initWithStyle:UItableVIEwCellStyleDefault reuseIDentifIEr:CellIDentifIEr];    }    cell.textLabel.text = [Nsstring stringWithFormat:@"%d",indexPath.row];    return cell;}#pragma mark - table vIEw delegate- (voID)tableVIEw:(UItableVIEw *)tableVIEw dIDSelectRowAtIndexPath:(NSIndexPath *)indexPath{    MyOtherVIEwController *vc = [[MyOtherVIEwController alloc] initWithNibname:nil bundle:nil];    [self.navigationController pushVIEwController:vc animated:YES];}

MyOtherVIEwController.m

- (ID)initWithNibname:(Nsstring *)nibnameOrNil bundle:(NSBundle *)nibBundleOrNil{    self = [super initWithNibname:nibnameOrNil bundle:nibBundleOrNil];    if (self) {        self.restorationIDentifIEr = @"detail";    }    return self;}- (voID)vIEwDIDLoad{    [super vIEwDIDLoad];    self.Title = @"Detail";    self.vIEw.backgroundcolor = [UIcolor redcolor];    self.vIEw.restorationIDentifIEr = @"detailVIEw";}
解决方法 因为您正在代码中创建您的详细视图控制器,并且不将其从故事板实例化,您需要实现一个还原类,因此系统还原过程知道如何创建详细视图控制器.

恢复类实际上只是一个工厂,它知道如何从恢复路径创建一个特定的视图控制器.你实际上不必为此创建一个单独的类,我们可以在MyOtherVIEwController中处理它:

在MyOtherVIEwController.h中,实现协议:UIVIEwControllerRestoration

然后在MyOtherVIEwController.m中设置recoverID时,还要设置还原类:

- (ID)initWithNibname:(Nsstring *)nibnameOrNil bundle:(NSBundle *)nibBundleOrNil{    self = [super initWithNibname:nibnameOrNil bundle:nibBundleOrNil];    if (self) {        self.restorationIDentifIEr = @"detail";        self.restorationClass = [self class]; //SET THE RESTORATION CLASS    }    return self;}

然后,您需要在恢复类(MyOtherVIEwController.m)中实现此方法

+(UIVIEwController *) vIEwControllerWithRestorationIDentifIErPath:(NSArray *)IDentifIErComponents coder:(NSCoder *)coder{   //At a minimum,just create an instance of the correct class.     return [[MyOtherVIEwController alloc] initWithNibname:nil bundle:nil];}

这可以让您恢复子系统能够创建并将Detail VIEw控制器推送到导航堆栈上. (你最初问的是什么)

扩展示例来处理状态

在一个真实的应用程序中,您需要同时保存状态并处理恢复它…我将以下属性定义添加到MyOtherVIEwController以模拟此:

@property (nonatomic,strong) Nsstring *selectedRecordID;

而且我还修改了MyOtherVIEwContoller的vIEwDIDLoad方法,将Detail标题设置为用户选择的任何记录ID:

- (voID)vIEwDIDLoad{    [super vIEwDIDLoad];  //  self.Title = @"Detail";    self.Title = self.selectedRecordID;    self.vIEw.backgroundcolor = [UIcolor redcolor];    self.vIEw.restorationIDentifIEr = @"detailVIEw";}

为了使该示例工作,在最初从MytableVIEwController中推送Detail VIEw时,设置selectedRecordID:

- (voID)tableVIEw:(UItableVIEw *)tableVIEw dIDSelectRowAtIndexPath:(NSIndexPath *)indexPath{    MyOtherVIEwController *vc = [[MyOtherVIEwController alloc] initWithNibname:nil bundle:nil];    vc.selectedRecordID = [Nsstring stringWithFormat:@"Section:%d,Row:%d",indexPath.section,indexPath.row];    [self.navigationController pushVIEwController:vc animated:YES];}

另一个缺失的部分是MyOtherVIEwController中的方法,您的详细信息视图,用于保存Detail控制器的状态.

-(voID)encodeRestorableStateWithCoder:(NSCoder *)coder{    [coder encodeObject:self.selectedRecordID forKey:@"selectedRecordID"];    [super encodeRestorableStateWithCoder:coder];}-(voID)decodeRestorableStateWithCoder:(NSCoder *)coder{     self.selectedRecordID = [coder decodeObjectForKey:@"selectedRecordID"];    [super decodeRestorableStateWithCoder:coder];}

现在这实际上还不行.这是因为在DecoreRestorablStateWithCoder方法之前的“VIEwDIDLoad”方法在恢复时被调用.因此,在显示视图之前,标题不会设置.要解决这个问题,我们处理在vIEwWillAppear中设置Detail视图控制器的标题:或者我们可以修改vIEwControllerWithRestorationIDentifIErPath方法来恢复创建类的状态:

+(UIVIEwController *) vIEwControllerWithRestorationIDentifIErPath:(NSArray *)IDentifIErComponents coder:(NSCoder *)coder{    MyOtherVIEwController *controller =  [[self alloc] initWithNibname:nil bundle:nil];    controller.selectedRecordID = [coder decodeObjectForKey:@"selectedRecordID"];    return controller;}

而已.

一些其他注意事项…

我假设你在App代表中做了以下,即使我没有看到代码?

-(BOol) application:(UIApplication *)application shouldSaveApplicationState:(NSCoder *)coder{    return YES;}- (BOol) application:(UIApplication *)application shouldRestoreApplicationState:(NSCoder *)coder {    return YES;}

在模拟器中运行演示代码时,我正确地保留了滚动偏移量,我看到有点薄弱.这似乎偶尔为我工作,但并不是所有的时间.我怀疑这可能是因为MytableVIEwController的真正恢复也应该使用一个restoreClass方法,因为它是在代码中实例化的.但是我还没有尝试过.

我的测试方法是将应用程序置于后台,返回跳板(需要保存应用程序状态),然后从XCode中重新启动应用程序以模拟干净的开始.

总结

以上是内存溢出为你收集整理的ios – UINavigationController状态恢复(无故事板)全部内容,希望文章能够帮你解决ios – UINavigationController状态恢复(无故事板)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1113544.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-29
下一篇2022-05-29

发表评论

登录后才能评论

评论列表(0条)

    保存