从情节提要重新加载视图时,以编程方式添加的 iOS 子视图会丢失
Posted
技术标签:
【中文标题】从情节提要重新加载视图时,以编程方式添加的 iOS 子视图会丢失【英文标题】:iOS Subviews added programmatically are lost when view is reloaded from the storyboard 【发布时间】:2012-06-12 20:21:14 【问题描述】:我有一个带有两个视图控制器的应用程序。 ViewControllerA 是一个分配了点击手势的空白视图,它允许用户在视图上进行选项卡并在点击点创建一个 UITextView。用户可以根据需要创建任意数量的 UITextView,然后以编程方式将它们添加到视图 (ViewControllerA) 作为子视图。
还有一个按钮允许用户更改文本字体和样式。这会触发第二个视图控制器 ViewControllerB 的 Segue,然后允许用户设置字体、文本大小、颜色等。一旦完成,用户单击 ViewControllerB 上的 DONE 按钮,另一个 Segue 切换回初始视图 (ViewControllerA)。
这一切都很好。除非用户从 ViewControllerB 切换回初始视图 (ViewControllerA),否则视图会从情节提要中重新加载,并且我以编程方式添加的子视图消失了。
在视图(ViewControllerA)中,ViewDidLoad 和 ViewWillAppear 触发得很好,所以问题似乎是在第一个 Segue 触发时释放了初始视图,然后在转换回来时从情节提要重新创建,但子视图当然不包括在内它们不在情节提要中,因为我以编程方式添加它们。
关于如何解决这个问题的最佳实践的任何建议,以便在主视图 (ViewControllerA) 重新加载时也重新创建子视图?
非常感谢您的任何建议!
【问题讨论】:
【参考方案1】:从问题看来,您对文本样式视图有一个转场,然后是另一个转场“回到原始” - 它不像那样工作,转场总是会创建目标 VC 的新实例。您应该对文本样式视图进行模态搜索,然后关闭模态视图控制器 - 这将返回到您的原始实例。
【讨论】:
【参考方案2】:为了记录,我解决了这个问题,以防其他人需要解决方案。
我在 ViewControllerA 中创建了一个子视图,它是主视图的大小,不包括工具栏。我称之为canvasView。然后我将我所有的 ImageViews 和 TextViews 添加到这个画布视图中。
然后在 ViewControllerA viewWillDisappear 中,我将 canvasView 及其所有子视图存档到这样的文件中。
NSString *archivePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"Canvas.archive"];
BOOL result = [NSKeyedArchiver archiveRootObject:_canvasView
toFile:archivePath];
if (!result)
NSLog(@"Archive failed to archivePath %@",archivePath);
然后在 ViewControllerA viewWillAppear 中检查是否存在现有存档,如果存在则重新加载它以正确顺序加载子视图。否则我会像这样创建一个空的 canvasView。
// If the collageView already exists then restore it from the achive, otherwise initialize a new one.
NSString *archivePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"Canvas.archive"];
_canvasView = [NSKeyedUnarchiver unarchiveObjectWithFile:archivePath];
if (_canvasView)
// Restore existing canvasView
[_backgroundView addSubview:_canvasView];
else
// Initialize a new canvasView
_canvasView = [[UIScrollView alloc] initWithFrame:CGRectMake(_backgroundView.frame.origin.x,
_backgroundView.frame.origin.y,
_backgroundView.frame.size.width,
_backgroundView.frame.size.height)];
[_backgroundView addSubview:_canvasView];
【讨论】:
其实我认为你把它复杂化了。从这个问题听起来你对文本样式视图有一个转场,然后是另一个转场“回到原来的” - 它不像那样工作,转场总是会创建目标 VC 的新实例。您应该对文本样式视图进行模态搜索,然后关闭模态视图控制器 - 这将返回到您的原始实例。 非常感谢 jrturton,这是一个更好的解决方案,无需完全归档。 在这种情况下,我已将其添加为答案。以上是关于从情节提要重新加载视图时,以编程方式添加的 iOS 子视图会丢失的主要内容,如果未能解决你的问题,请参考以下文章
如何从情节提要以编程方式加载 UIViewController?
如何在 ios swift 中以编程方式将情节提要视图控制器加载到标签栏控制器中?
如何以编程方式从情节提要中填充静态 UITableView?