在子视图中添加UIViewController

时间:2014-12-23 05:48:54

标签: ios objective-c uiview uiviewcontroller

我不知道这是否是搜索“在子视图中添加UIViewController”的正确键。 正如您在我的图像中看到的那样,有两个ViewController,主控制器和第二个控制器。在主控制器内部有一个UIView(蓝色背景色)。在UIView中,我想在我的UIView中添加第二个ViewController。我有这个代码,但它没有用。

enter image description here

这是我的代码

#import "ViewController.h"
#import "SampleViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *testView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    SampleViewController * sample = [[SampleViewController alloc] initWithNibName:@"SampleViewController" bundle:nil];
    sample.view.frame = CGRectMake(0, 0, self.testView.bounds.size.width, self.testView.bounds.size.height);
    [self.testView addSubview:sample.view];
} 

@end

我想知道这是否可行?我知道initWithNibName:可以在xib文件中使用,但我没有在谷歌搜索这个问题的确切术语。如果在IOS中可行的话,我只想尝试一些东西。希望你能理解我正在做的事情。希望得到你的建议。提前致谢

这是我的更新

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *testView;
@property(strong,nonatomic) SampleViewController * samples;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

UIStoryboard *storyBoard = self.storyboard;
SampleViewController * sample = [storyBoard instantiateViewControllerWithIdentifier:@"SampleViewController"]; 
// SampleViewController * sample = [[SampleViewController alloc] //initWithNibName:@"SampleViewController" bundle:nil];

[self displayContentController:sample];
//commented the below line because it is not needed here, use it when you want to remove        
//child view from parent.
 //[self hideContentController:sample];

}

- (void) displayContentController: (UIViewController*) content;
{
    [self addChildViewController:content];                 // 1
    content.view.bounds = self.testView.bounds;                 //2
    [self.testView addSubview:content.view];
    [content didMoveToParentViewController:self];          // 3
}


- (void) hideContentController: (UIViewController*) content
{
    [content willMoveToParentViewController:nil];  // 1
    [content.view removeFromSuperview];            // 2
    [content removeFromParentViewController];      // 3
}

我总是收到此错误

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle </Users/ace/Library/Developer/CoreSimulator/Devices/035D6DD6-B6A5-4213-9FCA-ECE06ED837EC/data/Containers/Bundle/Application/EB07DD14-A6FF-4CF5-A369-45D6DBD7C0ED/Addsubviewcontroller.app> (loaded)' with name 'SampleViewController''

我认为,它正在寻找一个笔尖。我没有在这里实现一个笔尖。

9 个答案:

答案 0 :(得分:44)

您应该使用Child containment概念,此处MainViewController是父视图控制器,您希望将子视图控制器视图添加为主视图控制器上的子视图。

添加和删除儿童

//call displayContentController to add SampleViewCOntroller view to mainViewcontroller
 [self displayContentController:sampleVCObject];

// write this method in MainViewController
- (void) displayContentController: (UIViewController*) content;
{
   [self addChildViewController:content];                 // 1
   content.view.bounds = testView.bounds;                 //2
   [testView addSubview:content.view];
   [content didMoveToParentViewController:self];          // 3
}

以下是代码的作用:

它调用容器的addChildViewController:方法来添加子项。调用addChildViewController:方法也会自动调用子进程的willMoveToParentViewController:方法。 它访问子视图属性以检索视图并将其添加到其自己的视图层次结构中。容器在添加视图之前设置子项的大小和位置;容器总是选择孩子的内容出现的位置。虽然此示例通过显式设置框架来执行此操作,但您也可以使用布局约束来确定视图的位置。 它显式调用子的didMoveToParentViewController:方法来表示操作已完成。

//you can also write this method in MainViewController to remove the child VC you added before.
- (void) hideContentController: (UIViewController*) content
{
   [content willMoveToParentViewController:nil];  // 1
   [content.view removeFromSuperview];            // 2
   [content removeFromParentViewController];      // 3
}

有关详细信息,请参阅apple doc: https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/ImplementingaContainerViewController.html

在Interface Builder中为那些不想编写代码的人配置容器。

要在设计时创建父子容器关系,请在故事板场景中添加容器视图对象,如图5-3所示。容器视图对象是占位符对象,表示子视图控制器的内容。使用该视图可以根据容器中的其他视图调整子视图的根视图的大小和位置。

Adding a container view in Interface Builder 使用一个或多个容器视图加载视图控制器时,Interface Builder还会加载与这些视图关联的子视图控制器。必须在父项的同时实例化子项,以便可以创建适当的父子关系。

答案 1 :(得分:13)

您只需使用StoryBoards

即可
  • 打开故事板并选择存在Blue视图的视图控制器,打开Utilities搜索ContainerView并将其拖到蓝色视图中,这将自动添加一个视图控制器,作为视图的子视图。您可以在大小检查器中调整容器视图的大小。

enter image description here

答案 2 :(得分:6)

我在第二个uiviewcontroller上解决了关于uiview的问题。 按照我使用过的代码:

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
SecondViewController *sb = (SecondViewController *)[storyboard instantiateViewControllerWithIdentifier:@"sb"];

sb.view.backgroundColor = [UIColor redColor];    
[sb willMoveToParentViewController:self];

[self.view addSubview:sb.view];

[self addChildViewController:sb];
[sb didMoveToParentViewController:self];

我希望能帮助你。

非常感谢

答案 3 :(得分:3)

从iOS5开始,你可以将一个childViewController添加到UIViewController中。 它是制作更小,更可重复使用的viewControllers的好方法,我也非常喜欢它。

你真的很亲密,但你只需要几行代码......

///
 [self addChildViewController:sample];

 [self.testView addSubview:sample.view]; //you already have this..

 [sample didMoveToParentViewController:self]; 

在你的viewWillDisappear:或者你需要清理的其他拆解方法之一:

//we'll need another pointer to sample, make it an iVar / property..
   [sample willMoveToParentViewController:nil];  // 1
   [sample removeFromSuperview];            // 2
   [sample removeFromParentViewController];      // 3

您可以在此处阅读有关包含子viewControllers的Apple文档https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/CreatingCustomContainerViewControllers/CreatingCustomContainerViewControllers.html

答案 4 :(得分:2)

SampleViewController * sample = [[SampleViewController alloc] initWithNibName:@"SampleViewController" bundle:nil];
sample.view.frame = CGRectMake(0, 0, self.testView.bounds.size.width, self.testView.bounds.size.height);

[self addChildViewController:sample];
[self.testView addSubview:sample.view];

答案 5 :(得分:2)

我想在子视图中添加UIViewController,这项工作。 在UIViewController上,我在.h文件中添加了2个按钮:

-(IBAction)matchButtonAction:(id)sender;
-(IBAction)closeButtonAction:(id)sender;

在.m文件中:

-(IBAction)matchButtonAction:(id)sender
{
    NSLog(@"matchButtonAction");
}
-(IBAction)closeButtonAction:(id)sender
{
    NSLog(@"closeButtonAction");
}

但我没有看到日志。

我需要在UIViewController上添加相同的参数instantiateViewControllerWithIdentifier?

如何解决问题?

我的UIViewController初始化是:

AlertDialogViewController *alertDialogView = (AlertDialogViewController *)[self.storyboard instantiateViewControllerWithIdentifier:@"alertDialogView"];         
        [alertDialogView willMoveToParentViewController:self];
        [viewController.view addSubview:alertDialogView.view];
        [viewController addChildViewController:alertDialogView];
        [alertDialogView didMoveToParentViewController:viewController];

答案 6 :(得分:1)

由于您的视图控制器位于故事板中,因此您应使用instantiateViewControllerWithIdentifier从故事板中获取VC。

SampleViewController * sample = [self.storyboard instantiateViewControllerWithIdentifier:@"IdOfSampleViewController"];
sample.view.frame = CGRectMake(0, 0, self.testView.bounds.size.width, self.testView.bounds.size.height);
[self.testView addSubview:sample.view];

不要忘记为故事板中的SampleViewController添加标识符

答案 7 :(得分:0)

我尝试使用此代码:

SecondViewController * secondViewController = [[SecondViewController alloc] initWithNibName:nil bundle:nil];

 secondViewController.view.frame = CGRectMake(0, 0, self.mySubView.bounds.size.width, self.mySubView.bounds.size.height);

 [self addChildViewController:secondViewController];
 [self.viewDialogSolution addSubview:secondViewController.view];

但我只看到myview而不是secondViewController的布局。

何解决问题?

非常感谢

答案 8 :(得分:0)

让控制器:SecondViewController = self.storyboard!.instantiateViewController(withIdentifier:“ secondViewController”)为! SecondViewController

controller.view.frame = self.view.bounds

controller.willMove(toParent:self)

self.view.addSubview(controller.view)

self.addChild(controller)

controller.didMove(toParent:self)