问题标签 [uikit-state-preservation]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
1748 浏览

ios - UICollectionView 状态恢复:自定义滚动位置

我正在尝试为元素可能四处移动的 UICollectionView 找到处理状态恢复的最佳方法。我的目标是确保在重新启动应用程序时,集合视图中最后查看的项目仍然可见,即使项目已经移动。例如,当应用程序被终止时,项目 A 位于索引 3 的单元格中,并且当应用程序重新启动时,如果模型说项目 A 应该显示在索引 4 处,我希望集合视图将偏移量初始化为索引 4 处的单元格.

正如文档所述,我认为在我的班级中实现UIDataSourceModelAssociation协议会为我解决这个问题:UICollectionViewDataSource

[UITableView 和 UICollectionView] 类使用该协议的方法来确保相同的数据对象(而不仅仅是相同的行索引)被滚动到视图中并被选中。

但是,我观察到的是,实现此协议确实会在恢复期间正确影响所选单元格的 indexPath (这对我的应用程序并不重要),但不会影响滚动位置。滚动位置(集合视图的 contentOffset)始终恢复到应用程序被终止时的确切位置,并且不受 UICollectionViewDataSource 的影响。

我确实有一个看起来像这样的解决方法。它与模型关联协议的模式基本相同,但我必须手动完成:

我是否误解了 UIDataSourceModelAssociation 的用法?有错误吗?有没有更优雅或更正确的方法来让它工作?

0 投票
1 回答
90 浏览

ios8 - XCode 6 中的 iOS 状态保存

我想在 XCode 6 和 iOS 8 中保留我的应用程序的状态。但是,我能找到的所有信息都是指情节提要和恢复标识符,但我没有使用情节提要。

我确信我可以理解所有这些,如果不是一件主要的事情:我似乎无法在 Xcode 6 中找到视图控制器的恢复 ID 字段。我找到了视图的字段,但是每个教程清楚地表明我必须确保标记控制器,而不是视图!

非常感谢任何帮助:)

提前谢谢

0 投票
1 回答
1148 浏览

ios - 标签栏和导航控制器应用程序中的状态恢复

目标:我正在尝试恢复基于选项卡控制器的应用程序的状态(每个选项卡上都有导航控制器)。

问题:重新启动时,所选选项卡似乎已按预期恢复,但所述选项卡内的导航层次结构却没有。

发展:

  1. 我首先从项目模板“基于选项卡的应用程序”开始。
  2. 接下来,我将恢复 ID 添加到子视图控制器和选项卡栏控制器。
  3. 在应用程序委托中,我实现了application(_:shouldSaveApplicationState:)application(_:shouldRestoreApplicationState:).

我运行然后应用程序,切换到第二个(右)选项卡,回家,终止。o 重新启动,显示右侧选项卡(如预期的那样)。到目前为止,一切都很好。

  1. 接下来,我转到故事板并将两个子视图控制器嵌入到各自的导航控制器中,并为它们分配恢复 ID。

我运行该应用程序,恢复仍然有效。还好。

  1. 接下来,我添加一个“细节”视图控制器;它的类是UIViewController故事板的自定义子类,具有配置调试标签内容及其视图背景颜色的属性。

  2. 我在每个选项卡的顶部视图控制器上放置了一个“显示详细信息...”按钮,并从每个选项卡创建一个 segue 到(共享)详细视图控制器。所以现在我的故事板看起来像一个六边形(另外,两个 segue 都在 Interface Builder 中设置了标识符)。因此,左右顶视图控制器共享相同类型的“细节”视图控制器。在展示时,它被配置为区别于它被推送的位置(见下一点)。

  3. 在每个顶视图控制器的prepareForSegue(_:sender:)方法中,我对推送的详细视图控制器进行了不同的配置:不同的文本和背景颜色(分别为“左”和蓝色,“右”和红色)。

  4. 我在细节视图控制器中添加了代码来保存和恢复文本和背景颜色属性的状态:encodeRestorableStateWithCoder(_:)decodeRestorableStateWithCoder(_:). 此外,我实施viewDidLoad()以在视图中反映这些属性的值。每当它被实例化并通过 segue 推入导航时,首先设置属性,然后用于在viewDidLoad(). 每当它在恢复过程中被实例化时,属性都会被设置decodeRestorableStateWithCoder(_:)并类似地用于viewDidLoad().

...但是当我运行此代码时,最后选择的选项卡会恢复,但只能恢复到顶部视图控制器-left 或 right-,而不是 detail。有趣的是,最后为细节视图控制器设置的背景颜色会瞬间闪烁。

encodeRestorableStateWithCoder(_:)我在and中放置了断点decodeRestorableStateWithCoder(_:),但只有第一个被执行(encode)。

  1. 想知道可能缺少什么,我继续实现了应用程序委托application(_:viewControllerWithRestorationIdentifierPath:coder:)(始终返回 nil,但记录传递的路径组件)。

关于是否需要这种方法,文档不是很清楚,并且在任何情况下,除了细节之外的所有视图控制器似乎都可以完美地恢复,即使没有它。我添加了代码以根据最后一个路径组件(即,该控制器的恢复 ID)实例化每个视图控制器并返回它。

现在,调用了decodeRestorableStateWithCoder(_:) 但导航仍会在一瞬间后返回到选项卡的顶部视图控制器。

那么发生了什么?在选项卡栏 + 导航控制器应用程序中实现状态保存和恢复我缺少什么?

0 投票
1 回答
243 浏览

ios - 在应用程序状态保存期间解决 SKAction 代码块编码限制的好方法是什么?

问题

当节点层次结构被编码时,正如在应用程序状态保存或“游戏保存”期间常见的那样,运行SKAction带有代码块的动作的节点必须特别处理,因为代码块不能被编码。

示例 1:动画后的延迟回调

在这里,一个兽人被杀了。它被动画淡出然后从节点层次结构中移除:

如果orc节点先编码再解码,动画会正常恢复,如预期的那样完整。

但是现在该示例被修改为使用在淡入淡出之后运行的代码块。一旦兽人(最终)死亡,代码可能会清理一些游戏状态。

不幸的是,代码块不会编码。在应用程序状态保存(或游戏保存)期间,如果此序列正在运行,则会发出警告:

SKAction:无法正确编码运行块动作,Objective-C 块不支持 NSCoding。

解码后,orc 会淡出并从 parent 中移除,但orcDidFinishDying:不会调用 cleanup 方法。

解决此限制的最佳方法是什么?

示例 2:补间

SKAction customActionWithDuration:actionBlock:似乎非常适合补间。我对这种事情的样板代码是这样的:

不幸的是,customActionWithDuration:actionBlock:无法编码。如果在动画期间保存游戏,则在游戏加载时将无法正确恢复。

同样,解决此限制的最佳方法是什么?

不完善的解决方案

这是我考虑过但不喜欢的解决方案。(也就是说,我很想阅读成功支持其中之一的答案。)

  • 不完善的解决方案:使用performSelector:onTarget:而不是runBlock:在动画中。这个解决方案是不完美的,因为参数不能传递给被调用的选择器;调用的上下文只能由目标和选择器的名称来表示。不是很好。

  • 不完善的解决方案:在编码期间,SKAction从任何相关节点中删除序列并推进程序状态,就好像序列已经完成一样。在第一个示例中,这意味着将节点alpha立即设置为0.0,从父节点中删除 orc 节点,然后调用orcDidFinishDying:. 这是一个不幸的解决方案,至少有两个原因:1)在编码期间需要特殊的处理代码;2)视觉上,节点将没有机会完成其动画。

  • 不完善的解决方案:在编码过程中,SKAction从任何相关节点中删除代码块,并在解码过程中重新创建它们。这是不平凡的。

  • 不完美的解决方案:永远不要使用SKAction代码块,尤其是在延迟之后。永远不要依赖动画的完成来恢复良好的应用程序状态。(如果您需要以可编码的方式安排未来的事件,请构建自己的事件队列而不使用代码块。)这个解决方案是不完美的,因为它非常有用,而且这将是一种耻辱(并且对于新手来说是一个反复出现的runBlock陷阱customActionWithDuration:actionBlock:) 认为他们是邪恶的。

0 投票
2 回答
197 浏览

ios - 如何防止 SKAction 序列在解码后重新启动?

我的应用程序是一个具有应用程序状态保存和恢复的 SpriteKit 游戏。当应用程序状态被保留时,我当前的大多数节点SKScene都被编码了。

当运行 an 的节点SKAction被编码和解码时,动作将从头开始。这似乎是标准SpriteKit行为。

对我来说,这种行为对于SKAction sequence. 在解码时,序列重新开始,无论它的组件操作已经完成了多少。例如,假设运行序列的代码如下所示:

如果应用程序状态在 10 秒等待期间被保留,然后恢复,则SKAction序列将从头重新开始,并带有第二个可见的淡出和淡入。

SKAction sequence应该显示与其他操作一致的解码行为是有道理的。但是,创建一个例外是有用的,这样任何已经完成的操作都不会再次运行。如何防止序列在解码后重新启动?

0 投票
0 回答
199 浏览

ios - 为什么我的导航堆栈在恢复应用程序时没有被保留?

因此,根据我在此处的帖子:为什么在状态恢复后更改我的应用程序的方向会解雇我的父视图控制器?我与另一个用户进行了讨论,我们得出的结论是这个问题与我的导航堆栈没有恢复有关。

该帖子的摘要 - 我可以从我恢复的 VC 成功地以模态方式呈现控制器,但是,当我旋转设备方向以显示一个模态呈现的视图控制器然后继续关闭该控制器时,应用程序不会返回到恢复的控制器。如果我不旋转屏幕,它会按预期工作。

我所有的控制器都通过故事板中的 segues 实例化。所有场景都在各自的情节提要中获得了修复标识符。我正在恢复的 VC 已成功恢复,但它不再是导航堆栈的一部分(navigationController 将变为 nil)。

这是我的应用程序的流程,直到我正在恢复的最后一个场景,其中 SWRevealController 是我用于我们应用程序侧边栏的库:

  1. Main.Storyboard - TempScreen (UIViewController)
  2. Navigation.Storyboard - SWRevealViewController
  3. Navigation.Storyboard - MenuTableViewController(SWRevealController 的后视图)
  4. Navigation.Storyboard - MyPlaces 的故事板参考(SWRevealController 的前视图)
  5. MyPlaces.storyboard - 地点,初始视图控制器
  6. MyPlaces.storyboard - 地点详情
  7. MyPlaces.storyboard - 交互的情节提要参考
  8. Interaction.storyboard - CreateInteraction(这是正在恢复的我遇到问题的场景)

正如你所看到的,有很多步骤可以到达我正在恢复的场景。我正在恢复的场景是通过按下按钮的 Push segue 到达的。

在打印identifierComponents中的viewControllerWithRestorationIdentifierPath方法内时AppDelegate,我发现了一些有趣的东西。以下是每次迭代打印的内容:

  1. 温度屏幕
  2. TempScreen、导航(SWRevealController 的后视图)
  3. TempScreen、导航、菜单表视图控制器
  4. TempScreen、Navigation、MyPlacesNavController(MyPlaces.storyboard 的初始化导航控制器)
  5. TempScreen、导航、MyPlacesNavController、地点 (VC)
  6. TempScreen、导航、MyPlacesNavController、Places (VC)、PlaceDetail
  7. TempScreen、Navigation、MyPlacesNavController、Interaction <--- Places 和 PlaceDetail 发生了什么?
0 投票
1 回答
2213 浏览

ios - 为什么我的 iOS 应用程序在返回前台模式后会从第一个屏幕重新启动?

当在详细屏幕中的我的 iOS 应用程序中时,我按下主页按钮,这将导致它进入后台模式。在 7 分钟左右不活动后,我重新启动它,但它并没有从我离开它的地方开始。它从第一个屏幕开始。

我上网,开始了解国家保护和恢复。我在一个屏幕上实现了,但它似乎不起作用。这就是我在 appDelegate.m 中所做的

以下代码在 appDelegate.m 中的 willFinishLaunchingWithOptions 方法中。我没有使用故事板,因为这个应用程序很旧。它有XIB。所以这个应用程序总是需要进入登录屏幕,检查是否存储了 accessToken,它将从登录屏幕进入主屏幕。如果未存储,它将保留在登录屏幕中。所以这是强制执行的。因此,只有一种方法可以像下面这样编码。

我已经在 viewDidLoad() 中为所有视图控制器提供了 restoreId,如下所示。例如,这就是我在 PetDetailViewController.m 中所做的

现在,当我进入 PetDetail 屏幕并按下主页按钮时,将调用 encodeRestorableStateWithCoder()。从 xcode 停止应用程序,重新启动它会停留在同一屏幕上,但会立即进入登录屏幕并转移到主屏幕(willFinishLaunchingWithOptions 中的代码可能正在执行)

我做错什么了吗?除非用户手动杀死它,否则如何防止应用程序从第一个屏幕重新启动?

0 投票
0 回答
11 浏览

swift - UIKit:将应用程序置于后台后,当应用程序返回焦点时,自定义表格视图标签文本为空

需要有关自定义表格视图单元格文本标签中的空白文本的一些指导。该表是使用 UIKit 和自定义 tableview 单元格构建的。

该表位于 UINavController 中。一切都按设计加载。自定义表格视图单元格有两个文本标签。将应用程序置于后台时会发生奇怪的行为。返回 tableview 后,两个文本标签之一为空白。如果我滚动,丢失的文本会返回。不明白为什么只有一个文本标签是空白的。行为永远不会改变。它始终是空白的相同文本标签。

我是否需要实现 UIDataSourceModel 协议来恢复表的状态,或者这里还有其他事情吗?

如果我需要实现 UIDataSourceModel,任何人都可以指出我要遵循的教程或示例吗?

别的

如果还有其他事情发生,有什么建议吗?

非常感谢