ios xcode storyboard Container View - 如何访问视图控制器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13275112/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 21:07:49  来源:igfitidea点击:

xcode storyboard Container View - How do I access the viewcontroller

iosobjective-cxcodeuiviewcontrollercontainer-view

提问by Justin808

I'm trying to use storyboard and get things working properly. I've added a a Container View to one of my existing views. When I try to add a reference to this in my view controller .hfile (ctrl-drag), I get a IBOutlet UIView *containerView. How do I get a reference to the container view's view controller instead? I need the container view controller so I can set it's delegate to my view's controller so they can "talk" to each other.

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

I have my story board setup as:

我的故事板设置为:

enter image description here

在此处输入图片说明

And its referenced in my .h file as:

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

enter image description here

在此处输入图片说明

Notice in the .h that is is a UIView, not my InstallViewController for the view. How do I add a reference to the view controller? I need to be able to set its delegate.

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

回答by DAXaholic

There is another solution by specifying an identifier for the embed segue(s) and retrieve the corresponding view controllers in method prepareForSegue:

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

The advantage of this way is that you needn't rely on a specific order in which your child view controllers are added due to the fact that each child view controller is embedded via an unique segue identifier.

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

Update 2013-01-17 - Example

更新 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_SegueIdEmbedDetailVCare constants with the corresponding ID of the segue IDs defined in the storyboard.

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

回答by vfranchi

When you add a container view the xcode calls the UIViewController method addChildViewController:

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

In your case, you can get the container ViewController looking for it on the SplashViewController's list of childViewControllers, something like this:

在您的情况下,您可以让容器 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;
    }
}

I had the same doubt yesterday :)

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

回答by Martin Stolz

The answer of Vitor Franchiis correct but could be more performant and convenient. Especially when accessing the child view controller several times.

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

Create a readonly property

创建只读属性

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

Then create a convenient getter method

然后创建一个方便的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;
}

From now on access the child view controller that way

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

[self.installViewController doSomething];

回答by Alexander Ney

If the nib is loaded it will call addChildViewController as part of the initialisation process

如果笔尖被加载,它会在初始化过程中调用 addChildViewController

so a performant solution could be also to overwrite

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

- (void)addChildViewController:(UIViewController *)childController

there you can catch your childController e.g. by comparing its Class and assign it to a property / ivar

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

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

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

}

}

This will save your from iterating trough the childViewControllers.

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

回答by John Verco

UIView* viewInsideOfContainer = installerView.subviews[0];

Will give you the UIView inside of the UIViewController that your controller UIView references. You can cast the subview to any type that inherits from UIView.

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