【问题标题】:ViewController addSubview视图控制器添加子视图
【发布时间】:2012-07-29 15:30:43
【问题描述】:

我快要疯了:

GolOlurActionViewController *golOlur = [[GolOlurActionViewController alloc] init];
[self.view addSubview:golOlur.view];

我有上面的代码,我在 IBACtion 内的 ViewController 中调用它。 GolOlurActionViewControllerViewController,你们都可以猜到。

当进程启动时,golOlur 的viewDidLoadviewDidAppear 方法被调用,但视图不呈现。

我已经尝试了我所知道的一切,但无法解决这个问题。

【问题讨论】:

  • 等等,我看错了你的代码。为什么要尝试将另一个视图控制器的视图作为子视图添加到这个视图中?这不是 ViewController 的工作方式。您创建一个视图控制器来控制 视图。使用时应将其推送为默认控制器。如果你只需要创建一个golOlur 视图来添加到你当前的视图中,你需要继承UIView--而不是UIViewController
  • 另外,当 IBAction 方法结束时,你有一个问题。如果您使用 ARC,您的 GolOlurActionViewController 将被释放,如果您与从中获取的视图进行交互,则会导致崩溃。如果不是 ARC,那就是内存泄漏。
  • @iremk 我同意 Wendi 的观点,即使用addSubview(令人惊讶地流行)转换到新视图的概念代表了视图控制器与视图角色的根本混淆。 不要使用addSubview 在视图控制器的主视图之间转换!
  • @PhillipMills 你当然是对的,但我认为你正在解决一个症状(泄漏或崩溃,取决于非 ARC 或 ARC),而不是问题。人们不应该使用addSubview 在视图之间进行转换。
  • @RobertRyan 是的,虽然我并不想尝试解决任何问题,而是尝试添加一些额外的细节,说明整个模式是如何触发其他 SDK 问题的。当我看到这一点时,我想到人们想要创建容器视图控制器而不采取必要的步骤来做到这一点。

标签: iphone objective-c ios uiviewcontroller addsubview


【解决方案1】:

如果您的意图是在视图之间转换,您真的不应该使用addSubview。如果这样做,您将不会收到旋转事件,因为您允许视图控制器层次结构与视图层次结构不同步。您应该只使用addSubview 将真正的子视图(例如UILabelUIImageViewUIButton 等,或者,如果执行正确的视图控制器包含等,则为子视图)添加到视图.使用addSubview 在视图之间转换代表了视图控制器和视图之间的基本混淆。

正确管理视图的关键是确保视图控制器层次结构与视图层次结构同步。最简单的方法是在视图控制器之间进行转换,让它们处理视图的呈现。因此,如果您使用的是 NIB,通常是:

GolOlurActionViewController *golOlur = [[GolOlurActionViewController alloc] initWithNibName:nil bundle:nil];
[self presentViewController:golOlur animated:YES completion:nil];

或者,带有导航控制器的 NIB:

GolOlurActionViewController *golOlur = [[GolOlurActionViewController alloc] initWithNibName:nil bundle:nil];
[self.navigationController pushViewController:golOlur animated:YES];

或者,如果您使用的是故事板(同样,如果您使用的是故事板,您可能会使用 segues 并且不需要任何这些,但只是为了完整起见):

GolOlurActionViewController *golOlur = [self.storyboard instantiateViewControllerWithIdentifier:@"GolOlurActionView"];
[self presentViewController:golOlur animated:YES completion:nil];

如果您的故事板使用导航控制器:

GolOlurActionViewController *golOlur = [self.storyboard instantiateViewControllerWithIdentifier:@"GolOlurActionView"];
[self.navigationController pushViewController:pushViewController:golOlur animated:YES];

万一您尝试进行控制器遏制,请告诉我们,因为这略有不同(需要调用 addChildViewControllerdidMoveToParentViewController),但如果您要在视图之间进行基本转换,正确的您的控制器的初始化以及随后对presentViewControllerpushViewController 的调用应该为您完成。

更新:

顺便说一句,如果您使用的是故事板(我不认为您是,但以防万一),而不是 instantiateViewControllerWithIdentifier,我实际上可能建议您在故事板上定义一个 segue,并提供Interface Builder中的一个标识符字符串,然后使用以下代码过渡到下一个场景:

[self performSegueWithIdentifier:@"yourIdentifier" sender:self];

如果您这样做,它会负责为您实例化您的控制器,并且您的整个应用程序的流程将准确地显示在情节提要中。

【讨论】:

    【解决方案2】:

    我相信您的问题是,当您按照自己的方式创建 UIViewController 时,您希望情节提要或 .xib 中的视图显示出来,但这是行不通的。您需要在情节提要中连接一个 push segue(这将需要 UINavigationController),或者以模态方式呈现新控制器,您也可以在情节提要中执行此操作。如果你有这个 ViewController 的 nib,你可以这样做:

     CustomViewController *controller = [[CustomViewController alloc] initWithNibName:@"CustomViewController.xib" bundle:[NSBundle mainBundle]];
    
     [self presentViewController:controller animated:YES completion:NULL];    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-03
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      相关资源
      最近更新 更多