【问题标题】:add UIViewController in subview在子视图中添加 UIViewController
【发布时间】:2015-02-21 06:22:45
【问题描述】:

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

这是我的代码

#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''

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

【问题讨论】:

  • 通过这个objc.io/issue-12/…学习
  • @user3818576 我根据您的需要编辑了我的答案,请使用它并告诉我,如果我能解决更多问题。
  • @user3818576 1. 您正在使用 nib 文件或情节提要?
  • 故事板。我没有 nib 文件
  • @user3818576 我终于编辑了你的代码,请使用它并告诉我。

标签: ios objective-c uiview uiviewcontroller


【解决方案1】:

让控制器:SecondViewController = self.storyboard!.instantiateViewController(withIdentifier: "secondViewController") as! 第二视图控制器

controller.view.frame = self.view.bounds

controller.willMove(toParent: self)

self.view.addSubview(controller.view)

self.addChild(控制器)

controller.didMove(toParent: self)

【讨论】:

    【解决方案2】:

    您应该使用子包含概念,这里 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 所示。容器视图对象是一个占位符对象,表示子视图控制器的内容。使用该视图来调整子视图相对于容器中其他视图的大小和位置。

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

    【讨论】:

    • @user3818576 仔细阅读此文档,将解决您的问题并帮助了解问题以备将来使用。
    • 你好桑迪普。我有这个错误“由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'无法在包中加载NIB”。我认为笔尖文件
    • @user3818576 请检查您是否在情节提要中设置了 StoryBoard ID“SampleViewController”并交叉检查名称。还要检查它是否被添加到编译目标。并检查视图和子视图是否正确连接到它们的 IBOutlets。
    • 请看我的更新帖。我想我已经走在正确的道路上了。对吗?
    【解决方案3】:

    您只需使用 StoryBoards 即可完成此操作

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

    【讨论】:

    • 你好拉基。这对我来说很好,但我想知道它是如何以编程方式工作的。感谢您的回答。我在这里向你学习
    • 所有其他答案都是以编程方式进行的......:)
    【解决方案4】:

    我正在尝试在子视图中添加 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];
    

    【讨论】:

    • 你能告诉如何删除它?
    【解决方案5】:

    我已经解决了关于第二个 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];
    

    希望能帮到你。

    非常感谢

    【讨论】:

      【解决方案6】:

      我尝试使用此代码:

      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 的布局。

      你能解决问题吗?

      非常感谢

      【讨论】:

      • 好的,现在我在主视图中看到了 uiviewcontroller,但是如何在 uiviewcontroller 中看到 uiview 内容?在 myuiviewcontroller 中,我设置了一个带有文本的 uiview,如何在我的主视图中看到它?
      • 我设置了一个viewvontroller红色背景,我看到红色但是我没有看到uiview?我需要链接2个视图控制器吗?我只创建了第二个视图控制器的布局并停止,我必须做点什么吗?
      • 你用过 UIStoryboard 吗?
      【解决方案7】:

      从 iOS5 开始你可以给 UIViewController 添加一个 childViewController。 这是制作更小、更可重用的 viewController 的好方法,我也非常喜欢它。

      你真的很接近,但你只需要多几行代码..

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

      在您看来WillDisappear: 或您需要像这样清理的其他拆卸方法之一:

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

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

      【讨论】:

      • 你好,杰夫,我对其他答案有同样的错误。我仍在试图弄清楚如何解决这个错误。 “由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'无法在包中加载NIB”
      • 您尝试在此处使用的初始化程序 initWithNibName:@"SampleViewController" bundle:nil 指定一个文件 SampleViewController.xib 。如果您没有这样的文件,则将 nibName Argument 更改为 nil 那里..
      【解决方案8】:

      由于您的视图控制器在情节提要中,您应该使用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 添加标识符

      【讨论】:

      • 这里没有错误,但是当我在第二个 ViewController 中添加按钮时。我在主程序中遇到错误。
      • 点击按钮?什么错误?可能是因为 SampleViewController 正在释放。
      • 您应该通过将 sample 作为 mainVC 的实例变量或将其添加为 childViewController 来防止释放,这也将按照其他人的建议工作
      • 好的,谢谢,我仍在试图弄清楚其他人试图实现什么。关于错误。它停在这里“return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));”在应用程序委托主中。
      • sample设为实例变量并试一试
      【解决方案9】:
      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];
      

      【讨论】:

      • 我在这里遇到了错误。对不起。但是当我将 initwithnibname 替换为 init 时。没有错误,但我的 uiview 中的输出为空。
      • 这里出现错误“由于未捕获的异常 'NSInternalInconsistencyException' 导致应用程序终止,原因:'无法在包中加载 NIB”。我认为笔尖文件,我不知道这个。对不起这里的菜鸟
      • @user3818576 是的,你需要用 Xib 设置它。
      猜你喜欢
      • 2017-01-26
      • 2011-10-02
      • 1970-01-01
      • 2013-04-21
      • 1970-01-01
      • 2010-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多