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
xcode storyboard Container View - How do I access the viewcontroller
提问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 .h
file (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:
我的故事板设置为:
And its referenced in my .h file as:
它在我的 .h 文件中被引用为:
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_SegueIdEmbedDetailVC
are 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 的任何类型。