我有一个视图控制器层次结构:
UIViewController
: A ,其中包含嵌入的子级UIPageViewController
。 A 在 B 之上覆盖各种内容,并通过导航和其他内容覆盖。UIPageViewController
: B 。实例化 A 时, B 会嵌入其中。我在 A 中覆盖prepareForSegue:sender
会导致 C 被实例化并设置为 B 的当前页面:
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([[segue identifier] isEqualToString: @"EmbedPagesSegue"])
{
UIPageViewController *const pagesViewController = [segue destinationViewController];
[pagesViewController setDataSource: self];
[pagesViewController setDelegate: self];
[self setPagesViewController: pagesViewController];
UIViewController *const initialPage = [self initialDisplayedPage];
[pagesViewController
setViewControllers: @[initialPage]
direction: UIPageViewControllerNavigationDirectionForward
animated: NO
completion:nil];
// Point X.
// Segue not yet started.
// A is not on screen yet!
// C has already been added to B
}
}
C 会覆盖viewDidAppearAnimated:
。
在显示初始页面时,在 C 的视图之前, C 的viewDidAppearAnimated:
会在点X 处调用可以在屏幕上,因为 B 尚未添加到 A (segue刚刚设置)。
这是一个问题,因为 C 的viewDidAppearAnimated:
实现需要能够引用它出现的 A 。
对于后续页面,嵌入segue已完成,因此 B 已添加到 A , 在屏幕上。在这些情况下,viewDidAppearAnimated:
对 C 的调用是合适的。
viewDidAppearAnimated:
实际上应该被称为viewDidAppearAnimatedInParentButTheParentMightNotHaveAppearedYet:
在此初始设置过程中, C 是否有一种干净的方法可以访问 A ?我可以做某种黑客,比如用performSelectorOnMainThread:withObject:waitUntilDone:
推迟设置,但我宁愿不这样做。
我是否以错误的方式实现嵌入segue?
这只是一个糟糕的设计 - 在这种情况下,反而是什么?
还有其他建议吗?
答案 0 :(得分:1)
通常,对视图或控制器层次结构的假设高于您所在的点是一个糟糕的设计。因此,通常不建议对父视图控制器或超级视图进行假设。在您的情况下,如果您需要从C访问A,请在C中创建公共API,您可以以某种形式(最有可能是weak
)传递A,以便它可以自行配置。