谷歌员工请注意,这个 QA 现在已经过时六年了!
正如下面的 Micky 和其他人所提到的,现在在 iOS 中每天都使用 Containers 来完成这项工作。
我有一个控制许多子视图的 ViewController。当我单击其中一个按钮时,我会初始化另一个视图控制器并将其视图显示为该视图的子视图。然而,子视图超出了子视图的框架边界,实际上填满了整个屏幕。
有什么问题?我认为问题在于 UIViewController 的视图有一个框架 (0,0,320,460),因此会填满整个屏幕(尽管它仅在子视图框架范围内触摸时才会接收触摸事件)。如何调整框架大小以适合子视图。
简而言之,我需要帮助将视图控制器的视图作为子视图添加到另一个视图控制器的视图中。
谢谢!
As of iOS 5,Apple 现在允许您制作 custom containers,以便将 UIViewController 添加到另一个 UIViewController,特别是通过 addChildViewController 等方法,因此确实可以嵌套 UIViewControllers
编辑:包括就地摘要以避免链接损坏
我引用:
iOS 提供了许多标准容器来帮助您组织应用程序。但是,有时您需要创建一个与任何系统容器提供的工作流都不匹配的自定义工作流。也许在您的设想中,您的应用程序需要一个特定的子视图控制器组织,它们之间具有专门的导航手势或动画转换。为此,您需要实现一个自定义容器 - 告诉我更多...
...和:
当你设计一个容器时,你在你的容器、父级和其他视图控制器、它的子级之间创建了明确的父子关系——告诉我更多
示例(由 Apple 文档提供)将另一个视图控制器的视图添加到容器的视图层次结构中
- (void) displayContentController: (UIViewController*) content
{
[self addChildViewController:content];
content.view.frame = [self frameForContentController];
[self.view addSubview:self.currentClientView];
[content didMoveToParentViewController:self];
}
多亏了这些人,我做到了http://highoncoding.com/Articles/848_Creating_iPad_Dashboard_Using_UIViewController_Containment.aspx
添加 UIView,将其连接到标题:
@property (weak, nonatomic) IBOutlet UIView *addViewToAddPlot;
在 - (void)viewDidLoad 中这样做:
ViewControllerToAdd *nonSystemsController = [[ViewControllerToAdd alloc] initWithNibName:@"ViewControllerToAdd" bundle:nil];
nonSystemsController.view.frame = self.addViewToAddPlot.bounds;
[self.addViewToAddPlot addSubview:nonSystemsController.view];
[self addChildViewController:nonSystemsController];
[nonSystemsController didMoveToParentViewController:self];
享受
这个答案对于旧版本的 iOS 是正确的,但现在已经过时了。您应该使用 Micky Duncan 的答案,其中涵盖了自定义容器。
不要这样做! UIViewController
的目的是驱动整个屏幕。它只是不适合这个,它并没有真正添加你需要的任何东西。
您所需要的只是一个拥有您的自定义视图的对象。只需使用 UIView
本身的子类,它就可以添加到您的窗口层次结构中,并且内存管理是全自动的。
将子视图 NIB 的所有者指向 UIView
的自定义子类。向这个自定义子类添加一个 contentView
出口,并将其指向笔尖内的视图。在自定义子类中执行以下操作:
- (id)initWithFrame: (CGRect)inFrame;
{
if ( (self = [super initWithFrame: inFrame]) ) {
[[NSBundle mainBundle] loadNibNamed: @"NibNameHere"
owner: self
options: nil];
contentView.size = inFrame.size;
// do extra loading here
[self addSubview: contentView];
}
return self;
}
- (void)dealloc;
{
self.contentView = nil;
// additional release here
[super dealloc];
}
(我在这里假设您使用 initWithFrame:
来构造子视图。)
我觉得所有这些答案都有些不完整,所以这是将 viewController 的视图添加为另一个 viewController 视图的子视图的正确方法:
[self addChildViewController:viewControllerToAdd];
[self.view addSubview:viewControllerToAdd.view];
[viewControllerToAdd didMoveToParentViewController:self];
如果您愿意,可以将其作为片段复制到您的代码中。 SO 似乎不理解代码替换格式,但它们会在 Xcode 中显示干净:
[self addChildViewController:<#viewControllerToAdd#>];
[self.view addSubview:<#viewControllerToAdd#>.view];
[<#viewControllerToAdd#> didMoveToParentViewController:self];
willMove 使用 addChild 自动调用。谢谢@iOSSergey
当您的自定义容器调用 addChildViewController: 方法时,它会在添加视图控制器之前自动调用要添加为子视图控制器的 willMoveToParentViewController: 方法。
利用:
[self.view addSubview:obj.view];
更改 viewcontroller.view.frame
的帧大小,然后添加到子视图。 [viewcontrollerparent.view addSubview:viewcontroller.view]
您必须设置边界属性以适合该框架。 frame 其 superview 属性,并且 bounds 将 frame 限制在 view 本身的坐标系中。
您可以将 PopupController 用于将 UIViewController 显示为子视图的 SDK 您可以检查 PopupController
这是相同的示例代码
popup = PopupController
.create(self.navigationController!)
.customize(
[
.layout(.center),
.animation(.fadeIn),
.backgroundStyle(.blackFilter(alpha: 0.8)),
.dismissWhenTaps(true),
.scrollable(true)
]
)
.didShowHandler { popup in
}
.didCloseHandler { popup in
}
let container = MTMPlayerAndCardSelectionVC.instance()
container.closeHandler = {() in
self.popup.dismiss()
}
popup.show(container)
currentClientView
的作用是什么?我在文档中根本无法理解。