
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状态恢复(无故事板)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)