从故事板重新加载视图时,以编程方式添加的iOS子视图会丢失

时间:2012-06-12 20:21:15

标签: ios storyboard automatic-ref-counting subviews

我有一个带有两个视图控制器的应用程序。 ViewControllerA是一个空白视图,其中分配了一个轻击手势,允许用户在视图上进行选项卡并在点击时创建一个UITextView。用户可以根据需要创建任意数量的UITextView,然后以编程方式将它们添加到视图(ViewControllerA)作为子视图。

还有一个按钮,允许用户更改文本字体和样式。这会触发第二个视图控制器ViewControllerB的Segue,然后允许用户设置Font,Text Size,Color等。一旦完成,用户单击ViewControllerB上的DONE按钮,另一个Segue切换回初始视图(ViewControllerA)。

一切正常。除非用户从ViewControllerB切换回初始视图(ViewControllerA),否则视图将从故事板重新加载,并且我以编程方式添加的子视图已消失。

在视图中(ViewControllerA)ViewDidLoad和ViewWillAppear正好被解雇所以问题似乎是当第一个Segue触发时从初始视图中释放,然后在转换回来时从故事板重新创建,但子视图当然不包括在内因为我以编程方式添加它们,所以它们不在故事板中。

有关如何解决此问题的最佳做法的任何建议,以便在主视图(ViewControllerA)重新加载时重新创建子视图?

非常感谢任何建议!

2 个答案:

答案 0 :(得分:1)

为了记录,我解决了以下问题,以防其他人需要解决方案。

我在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];
}

答案 1 :(得分:1)

从问题看起来你有一个文本样式视图的segue,然后另一个segue“回到原始” - 它不能像那样工作,segues总是创建目标VC的新实例。你应该有一个模式segue到文本样式视图,然后解散模态视图控制器 - 这将返回到您的原始实例。