关于iPhone应用状态的另一个问题

时间:2009-04-07 09:00:31

标签: iphone objective-c cocoa state nsuserdefaults

我还有一个关于在iPhone上恢复应用程序状态的问题。 简单数据(如所选选项卡)可以存储在NSUserDefaults中,但这还不够。

我想恢复整个状态,包括导航控制器(转到子子视图控制器)。

我的问题是我的应用程序分为几个xib文件,因此在开始时,并未实例化所有视图控制器。 有没有办法从xib文件“强制”实例化?

(我手边没有代码,但如果不清楚,我可以尝试写一个小端)

非常感谢。

3 个答案:

答案 0 :(得分:5)

调用[viewController view]将确保加载给定视图控制器的XIB;一旦它,你可以正常使用它的任何其他属性。

这是我倾向于做的事情:

@class Record;  // some model object--I assume it has an integer record ID
@class DetailViewController;

@interface RootViewController : UIViewController {
    IBOutlet DetailViewController * detailController;
}

- (void)restore;
...
@end

@implementation RootViewController

// Note: all detailController showings--even ones from within 
// RootViewController--should go through this method.
- (void)showRecord:(Record*)record animated:(BOOL)animated {
    [self view];    // ensures detailController is loaded

    [[NSUserDefaults standardUserDefaults] setInteger:record.recordID 
                                               forKey:@"record"];
    detailController.record = record;

    [self.navigationController pushViewController:detailController 
                                         animated:animated];
}

- (void)restore {
    int recordID = [[NSUserDefaults standardUserDefaults] integerForKey:@"record"];

    if(recordID) {
        Record * record = [Record recordWithID:recordID];
        [rootViewController showRecord:record animated:NO];
        // If DetailViewController has its own state to restore, add this here:
        // [detailController restore];
    }
}
...
- (void)viewDidAppear:(BOOL)animated {
    [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"record"];
}
@end

@implementation MyAppDelegate

- (void)applicationDidFinishLaunching:(UIApplication*)application {
    ...
    [rootViewController restore];
    ...
}
...
@end

视图层次结构的每个级别都会处理自己的状态保存,因此应用程序控制器不必了解所有可能的视图以及它们可能处于哪个订单。

答案 1 :(得分:4)

我在我的应用程序Litho Graph中执行此操作。如果您在退出时处于某个页面上,则下次启动时会将您还原到该页面。这也很简单:在我的主视图控制器的-viewDidLoad实现中,我检查用户默认值中的最后一页查看键。如果没有,我会继续正常(并显示所有页面的列表)。如果有什么,我打开那个页面(将新的视图控制器推到导航控制器堆栈上)。

视图控制器的实际加载非常简单:我只是实例化它们。我的每个视图控制器类都重写了-init以调用-initWithNibName:bundle:on super,因此调用+ alloc和-init来创建视图控制器实例足以从相应的.xib文件加载它。然后,如上所述,我将它推到导航控制器的堆栈上:

[self.navigationController pushViewController: controller animated: YES];

当然,你可以根据需要深入了解多个图层,但请记住,如果要进行多次转换,您可能需要在没有动画的情况下推动视图控制器。用户必须等待几个动画才会适得其反((

答案 2 :(得分:0)

查看苹果“drilldownsave”示例代码。完全符合你的要求