xcode storyboard容器视图 - 如何访问viewcontroller

时间:2012-11-07 17:38:04

标签: ios objective-c xcode uiviewcontroller container-view

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

我将故事板设置为:

enter image description here

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

enter image description here

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

5 个答案:

答案 0 :(得分:69)

通过指定嵌入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。

答案 1 :(得分: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;
    }
}

昨天我有同样的疑问:)

答案 2 :(得分: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];

答案 3 :(得分:0)

UIView* viewInsideOfContainer = installerView.subviews[0];

将在你的控制器UIView引用的UIViewController里面给你UIView。您可以将子视图转换为从UIView继承的任何类型。

答案 4 :(得分:0)

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

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

- (void)addChildViewController:(UIViewController *)childController

你可以抓住你的childController,例如通过比较它的类并将其分配给属性/ ivar

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

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

}

这将通过childViewControllers保存您的迭代。