11

这可能是不可能的,但我试图在场景转换之间保存我的应用程序的状态,但我不知道该怎么做。目前我喜欢这样的方式,当你运行一个应用程序并点击主页按钮时,你可以回到你离开的那个应用程序,但是如果你在场景之间转换(在故事板中),一旦你回到那个场景应用程序状态未保存。

我只有两个不同的场景需要保存(你从一个到另一个来回转换)。如何在不占用精确内存的情况下保存故事板场景状态?

更详细:这是我的整个故事板。您可以使用加号工具栏按钮在场景之间来回切换。在第二个场景中,用户可以点击表格视图单元格,一个真实的图像将填充图像视图(见图 1.2)

图 1.1图 1.1

在图 1.2 中,您可以看到当您点击多个表格视图单元之一时会发生什么(弹出一个图像视图。)

图 1.2图 1.2

问题:当您点击填充图像视图的表格视图单元格时(如图 1.2 所示),如果您停留在该场景甚至点击 iPhone 主页按钮(如果您点击 iPhone 主页按钮然后重新打开app 场景的状态已保存,充满简单图像的图像视图仍然像我们离开它一样显示),但是如果我(使用加号按钮)转换回第一个场景,然后在第一个场景上使用加号按钮回到第二个场景,我创建的图像视图(如图 1.2 所示)消失了,第二个场景在加载时没有保存我们填充的状态和图像视图。

编辑:我尝试对两个场景使用相同的视图控制器,但它没有解决问题。

更新:我刚刚找到以下代码(我认为存储视图状态)。我怎么能用这个,这就是我一直在寻找的吗?

MyViewController *myViewController=[MyViewController alloc] initWithNibName:@"myView" bundle:nil];
[[self navigationController] pushViewController:myViewController animated:YES];
[myViewController release];
4

7 回答 7

2

图 1.1 有一个根本缺陷,我认为这是您问题的基础。

Segues(故事板上控制器之间的箭头)创建版本的UIViewControllers. 你有循环序列。因此,当您通过 segue “返回”到原始屏幕时,实际上是通过创建新版本来带您前进。

这可能会给内存使用带来重大问题,但这也意味着您无法维护状态,因为每个新创建的项目都是空的。

由于您使用的是 aUINavigationController并且pushViewController:animated:您应该“弹出”您的控制器以摆脱它。

在您的“第二个”场景中,从 + 按钮中删除 segue 并创建IBAction一个touchUpInside事件。在IBAction代码中添加“pop”

- (IBAction)plusButtonTapped {
    [self.navigationController popViewControllerAnimated:YES];
}
于 2012-04-24T20:28:36.597 回答
2

我建议将两件事结合起来:1. 接受DBD的建议并确保您不会不断创建新视图 2. 创建一个共享类作为数据控制器(对于高尔夫球手,以便数据是独立的现场)

制作segues的正确方法是让一个从左侧的视图控制器引导到右侧的视图控制器。但是,要关闭右侧的那个,您可以使用

-(IBAction)buttonPushed:(id)sender 
      [self dismissModalViewControllerAnimated:YES];
}

这将带您回到左侧的视图控制器,左侧的视图控制器处于其原始状态。现在的问题是如何保存右边的数据。

为此,您可以创建一个单例类。单例类只有一个实例,所以无论你去右边的视图控制器多少次,数据总是一样的。

单例类实现(名为 DataManager 的类) - 标题

@interface DataManager : NSObject {
}

+(id)initializeData;
-(id)init;
@end

单例类实现(一个名为 DataManager 的类) - 主要

static DataManager *sharedDataManager = nil;

@implementation DataManager
+(id)initializeData {
    @synchronized(self) {
        if (sharedDataManager == nil)
            sharedDataManager = [[self alloc] init];
    }
    return sharedDataManager;
}

-(id)init { 
    if(self == [super init]) {
    } 
    return self;
}
@end

然后,在您的视图控制器代码中,您可以像这样获取此实例

DataManager *sharedDataManager = [DataManager initializeDataManager];

这样,无论您切换多少次视图,您都将拥有相同的数据。此外,您可以通过将数据和视图控制器分开来更好地遵守 MVC 编程。(http://en.wikipedia.org/wiki/Model-view-controller

于 2012-04-25T00:19:46.327 回答
0

我明白你的意思了。这应该发生在每个应用程序中,因为当导航堆栈中的最后一个视图控制器被转换离开时,它会被释放和释放。如果您需要保存诸如文本或对象位置之类的值,plist 可能是要走的路。有关如何使用 plist 的信息,请参阅此相关问题。

于 2012-04-15T23:33:30.630 回答
0

苹果不会为你做这件事。您可能应该只使用 NSUserDefaults 保存每个视图的状态,并且每次应用程序启动时重新加载您保存的数据。

如果您将所有内容存储在 CoreData 中,您只需要保存活动视图和一些对象 ID,否则您需要保存您拥有的任何数据。

不要指望 iOS 会在两次启动之间保存您在内存中的任何内容。只需将其存储在 NSUserDefaults 中并每次加载即可。

于 2012-04-24T01:16:58.863 回答
0

将场景的状态存储在 NSUserDefaults 或 plist 文件中,然后在加载场景时只需从那里加载设置即可。如果图像是从 Internet 加载的,您可能还希望将它们本地保存在您的 iphone 硬盘驱动器上,以便运行更顺畅。

于 2012-04-24T09:30:31.493 回答
0

我认为您不应该循环使用segues,只需使用从viewcontroller 2 连接viewcontroller 1 的一个就足够了,这样您就可以确保没有制作额外的viewcontrollers(可能是内存问题?)

但是对于您的特定问题,我认为您应该使用核心数据来保存表的确切状态,查看,因为 ios 不会始终保存视图的确切状态。这将需要工作,但你会实现你想要的。您将需要保存确切的照片(使用将保存的代码或枚举)、表格视图中的位置、分数或保存该状态所需的任何数据。

最棒的是,coredata 非常高效,以至于在应用程序重新启动或进入前台时重新加载数据不需要时间,并且到目前为止,我使用 core data 加载了超过 5k 的记录并且工作得很好,而且速度并不慢全部。

当我回到家时,我会提供一个代码,您可能会用它来了解我的意思。

于 2012-04-24T21:11:51.573 回答
0

这里的关键是:

  1. 为您的应用程序所需的数据提供某种存储。这是您的应用程序的数据模型。

  2. 让每个视图控制器访问模型,或者至少访问它需要完成工作的模型部分。然后,视图控制器可以使用模型中的数据在它创建时或视图即将出现时对其进行配置。

  3. 让每个视图控制器在适当的时间更新模型,例如当视图即将消失时,甚至是每次用户进行更改时。

您可以通过多种方式在内存中组织数据,并且可以通过多种方式将其存储在磁盘上(即长期存储)。属性列表、核心数据、普通旧数据文件和密钥存档都是将数据写入文件的可能性。NSArray、NSDictionary、NSSet 等都是可以用来帮助您在内存中组织数据的类。不过,这些都与让您的视图控制器感觉持久没有任何关系。当然,你会使用它们,但你选择哪一个并不重要,就更新你的视图控制器而言。同样重要的是,您拥有某种模型,并且您的视图控制器可以访问它。

通常,应用程序委托设置模型,然后根据需要将其传递给视图控制器。

其他可能有帮助的事情是,当您的视图控制器从导航堆栈中弹出时,您不必让它们被删除如果需要,您可以在应用程序委托中设置两个视图控制器,以便它们保持不变。然后,您可以使用已有的,而不是一直创建新的,这样做您会自动获得某种程度的持久性。

于 2012-04-25T00:36:30.470 回答