2012-04-15 25 views
11

这可能是不可能的,但我试图保存我的应用程序在场景转换之间的状态,但我无法弄清楚该做什么。目前我喜欢这种方式,当你有一个应用程序运行并点击主页按钮时,你可以回到那个应用程序的位置,但如果你在场景之间切换(在故事板中),一旦你回到那个场景应用程序状态未保存。保存iOS应用程序场景状态

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

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

Figure 1.1图1.1

在图1.2,你看,当你点击里面一个发生了什么许多表视图细胞(图像视图弹出。)

Figure 1.2图1.2

该问题:当你点击表格视图细胞,填补的图像视图(在图1.2示出)它如果你停留在那个场景或者甚至是没有问题的话,它会很好的工作点击iPhone主页按钮(如果你点击iPhone主页按钮,然后重新打开应用程序,场景的状态被保存,图像视图充满了简单的图像仍然显示,就像我们离开它一样),但如果我转换(使用加号按钮)回到第一个场景,然后使用第一个场景上的加号按钮回到第二个场景,我创建的图像视图(如图1.2所示)消失,第二个场景加载而不保存状态和图像视图,我们填充。

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

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

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

操作系统应该为你保存'场景'。你的情况有什么特别的不同? – CodaFi 2012-04-15 23:24:27

+0

当我点击home按钮并重新打开应用程序时,它会保存场景的状态,但当我转换到其他场景并返回时,它不会保存场景。 – 2012-04-15 23:27:29

回答

2

我建议两两件事的组合: 1.取DBD的建议,并确保你没有不断地创造新的观点 2.创建一个共享类是数据控制器(用于高尔夫球手,以使数据与场景无关)

使segues正确的方法是从左侧的视图控制器到右侧的视图控制器。然而,驳回右边的一个,你可以使用

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

这将带你回到了视图控制器的左侧,与左侧的原始状态视图控制器。现在的问题是如何保存右侧的数据。

要做到这一点,你可以创建一个单例类。 Singleton类只有一个实例,因此无论您转到右侧的视图控制器多少次,数据总是相同的。

辛格尔顿类实现(一类叫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

0

我明白你的意思了。这应该发生在每个应用程序上,因为当导航堆栈中的最后一个视图控制器被转换离开时,它将被释放并释放。如果您需要保存诸如文字或对象位置等值,则可能需要使用plist。有关如何使用plist,请参见this related question

+0

有什么办法我不能释放/释放场景 – 2012-04-16 01:02:58

+0

我从来没有听说过UIViewController单身......我想这是可能的。 – CodaFi 2012-04-16 02:30:02

0

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

如果你正在CoreData中存储所有东西,你只需要保存活动视图和一些对象标识符,如果没有,你需要保存你所有的数据。

不要期望iOS在启动时保存内存中的任何内容。只需将它存储在NSUserDefaults中并每次加载它。

+0

我将如何存储场景的状态?我会存储什么对象?你能告诉我示例代码吗? - 我是iOS和客观的新手... – 2012-04-24 11:04:22

0

将场景的状态存储在NSUserDefaults中或放置在plist文件中,然后在加载场景时只需使用该场景中的设置加载它。如果图像是从互联网上加载的,你可能也想将它们保存在你的iphones硬盘上,这样它会更流畅一些。

+0

我将如何存储场景的状态?我会存储什么对象?你能告诉我示例代码吗? – 2012-04-24 11:02:41

2

图1.1有一个根本的缺陷,我相信你的问题的基础。

Segges(故事板上的控制器之间的箭头)创建新的版本的UIViewControllers。你有循环赛段。所以当你通过segue回到原来的屏幕时,通过创建一个新版本真的让你前进。

这可能会造成内存使用的一个主要问题,但这也意味着您无法维护状态,因为每个新创建的项目都是空白的。

由于您使用UINavigationControllerpushViewController:animated:您应该“弹出”您的控制器以摆脱它。

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

- (IBAction)plusButtonTapped { 
    [self.navigationController popViewControllerAnimated:YES]; 
} 
+0

其实我没有使用UINavigation Controller,我该如何在我的场景中实现它? – 2012-04-24 21:05:02

+0

在您的代码中,您提到使用'[[self navigationController] pushViewController:myViewController animated:YES];'显示您的第二个screne,这意味着您正在使用'UINavigationController' – DBD 2012-04-25 02:26:28

0

我不认为你应该循环塞格斯,只需使用一个连接从视图 - 控制2的ViewController 1应该是够了,这样你确保没有额外viewcontrollers (内存问题可能?)

但是,对于你的特定问题,我相信你应该使用核心数据来保存你的表的确切状态,查看,因为ios并没有保存完全的视图状态倍。这将需要工作,但你会达到你想要的。您需要保存确切的照片(使用将保存的代码或枚举),表格视图中的位置,分数或任何您需要保存该数据的数据。

最棒的是,coredata非常高效,可以在应用程序重新映射或重新加载数据时重新加载数据,而无需花费时间,并且使用核心数据加载超过5k条记录,直到现在,并且工作得很好,它一点都不慢。

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

0

这里的关键是:

  1. 有某种存储的数据,你的应用需求。这是你的应用程序的数据模型。

  2. 为每个视图控制器提供对模型的访问权限,或者至少对模型中需要执行其工作的部分进行访问。然后,视图控制器可以使用模型中的数据在创建时或者即将显示视图时对其进行配置。

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

有很多,你可以在内存中组织数据的方式,并且有很多的方式,你可以将其存储在磁盘上(即,在长期储存)。属性列表,核心数据,普通旧数据文件和键控归档都是将数据写入文件的可能性。 NSArray,NSDictionary,NSSet等都是您可以用来帮助您在内存中组织数据的类。尽管如此,没有任何关系让你的视图控制器保持持久性。你肯定会使用它们,但是你选择哪一个并不重要,只要更新视图控制器就行了。重要的是,你有一些模型,并且你的视图控制器可以访问它。

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

可能有帮助的东西是,你不需要让您的视图控制器在弹出导航堆栈时被删除。如果需要,您可以在应用程序委托中设置两个视图控制器,以便它们继续存在。然后你可以使用你得到的那些,而不是一直创建新的,这样你会自动获得一定程度的持久性。