50

我正在尝试使用情节提要并使事情正常工作。我已将一个容器视图添加到我现有的视图之一。当我尝试在我的视图控制器.h文件(ctrl-drag)中添加对此的引用时,我得到一个IBOutlet UIView *containerView. 如何获取对容器视图的视图控制器的引用?我需要容器视图控制器,这样我就可以将它设置为我的视图控制器的委托,这样它们就可以相互“交谈”。

我的故事板设置为:

在此处输入图像描述

它在我的 .h 文件中引用为:

在此处输入图像描述

请注意 .h 中的 UIView,而不是视图的 InstallViewController。如何添加对视图控制器的引用?我需要能够设置它的委托。

4

5 回答 5

70

还有另一种解决方案,方法是为嵌入 segue 指定一个标识符并在方法中检索相应的视图控制器prepareForSegue:

这种方式的优点是您不需要依赖添加子视图控制器的特定顺序,因为每个子视图控制器都是通过唯一的 segue 标识符嵌入的。

2013-01-17 更新 - 示例

- (void) prepareForSegue:(UIStoryboardSegue*)segue sender:(id)sender
{
    // -- Master View Controller
    if ([segue.identifier isEqualToString:c_SegueIdEmbedMasterVC])
    {
        self.masterViewController = segue.destinationViewController;
        // ...
    }
    // -- Detail View Controller
    else if ([segue.identifier isEqualToString:c_SegueIdEmbedDetailVC])
    {
        self.detailViewController = segue.destinationViewController;
        // ...
    }
}

c_SegueIdEmbedMasterVC&c_SegueIdEmbedDetailVC是具有故事板中定义的 segue ID 的相应 ID 的常量。

于 2012-11-16T17:00:15.783 回答
14

当您添加容器视图时,xcode 会调用 UIViewController 方法addChildViewController:

在您的情况下,您可以让容器 ViewController 在 SplashViewController 的列表中查找它childViewControllers,如下所示:

for (UIViewController *childViewController in [self childViewControllers])
{
    if ([childViewController isKindOfClass:[InstallViewController class]])
    {
        //found container view controller
        InstallViewController *installViewController = (InstallViewController *)childViewController;

        //do something with your container view viewcontroller

        break;
    }
}

昨天我也有同样的疑问:)

于 2012-11-09T14:04:23.167 回答
2

Vitor Franchi的答案是正确的,但可能更高效、更方便。特别是在多次访问子视图控制器时。

创建只读属性

@interface MyViewController ()
@property (nonatomic, weak, readonly) InstallViewController *cachedInstallViewController;
@end

然后创建一个方便的getter方法

- (InstallViewController *)installViewController
{
    if (_cachedInstallViewController) return _cachedInstallViewController;

    __block InstallViewController *blockInstallViewController = nil;
    NSArray *childViewControllers = self.childViewControllers;
    [childViewControllers enumerateObjectsUsingBlock:^(id childViewController, NSUInteger idx, BOOL *stop) {

        if ([childViewController isMemberOfClass:InstallViewController.class])
        {
            blockInstallViewController = childViewController;
            *stop = YES;
        }
    }];

    _cachedInstallViewController = blockInstallViewController;

    return _cachedInstallViewController;
}

从现在开始以这种方式访问​​子视图控制器

[self.installViewController doSomething];
于 2014-03-31T10:53:27.453 回答
0
UIView* viewInsideOfContainer = installerView.subviews[0];

将为您提供控制器 UIView 引用的 UIViewController 内的 UIView。您可以将子视图转换为从 UIView 继承的任何类型。

于 2013-05-17T17:37:43.223 回答
0

如果 nib 被加载,它将调用 addChildViewController 作为初始化过程的一部分

所以一个高性能的解决方案也可以覆盖

- (void)addChildViewController:(UIViewController *)childController

在那里你可以捕捉你的 childController 例如通过比较它的 Class 并将它分配给一个属性/ ivar

-(void)addChildViewController:(UIViewController *)childController
{
    [super addChildViewController:childController];

    if([childController isKindOfClass:[InstallViewController class]])
    {
        self.installViewController = (InstallViewController *)childController;
    }

}

这将使您免于通过 childViewControllers 进行迭代。

于 2014-03-31T11:35:08.583 回答