addChildViewController 实际上做了什么?

2023-12-13

我刚刚第一次涉足 iOS 开发,我要做的第一件事就是实现一个自定义容器视图控制器- 我们称之为SideBarViewController- 交换它显示的几个可能的子视图控制器中的哪一个,几乎与标准完全相同标签栏控制器。 (这几乎是一个标签栏控制器但有一个可隐藏的侧面菜单而不是标签栏。)

根据苹果文档中的说明,我调用addChildViewController每当我将子 ViewController 添加到容器中时。我用于交换当前子视图控制器的代码SideBarViewController看起来像这样:

- (void)showViewController:(UIViewController *)newViewController {
    UIViewController* oldViewController = [self.childViewControllers 
                                           objectAtIndex:0];
    
    [oldViewController removeFromParentViewController];
    [oldViewController.view removeFromSuperview];
    
    newViewController.view.frame = CGRectMake(
        0, 0, self.view.frame.size.width, self.view.frame.size.height
    );
    [self addChildViewController: newViewController];
    [self.view addSubview: newViewController.view];
}

然后我开始试图弄清楚到底是什么addChildViewController在这里,我意识到我不知道。除了贴新的ViewController in the .childViewControllers数组,似乎对什么都没有影响。即使我从不调用,从子控制器视图到我在故事板上设置的子控制器的操作和出口仍然可以正常工作addChildViewController,我无法想象它还会影响什么。

事实上,如果我重写我的代码以不调用addChildViewController,而是看起来像这样......

- (void)showViewController:(UIViewController *)newViewController {

    // Get the current child from a member variable of `SideBarViewController`
    UIViewController* oldViewController = currentChildViewController;

    [oldViewController.view removeFromSuperview];

    newViewController.view.frame = CGRectMake(
        0, 0, self.view.frame.size.width, self.view.frame.size.height
    );
    [self.view addSubview: newViewController.view];

    currentChildViewController = newViewController;
}

...据我所知,我的应用程序仍然可以完美运行!

Apple 文档并没有详细说明什么addChildViewController确实如此,或者为什么我们应该这样称呼它。该方法的作用或为什么应在该方法的相应部分中使用该方法的相关描述的完整范围UIViewController类参考目前是:

将给定的视图控制器添加为子视图控制器。 ... 此方法仅旨在由自定义容器视图控制器的实现调用。如果重写此方法,则必须在实现中调用 super。

同一页前面还有这一段:

在将子视图控制器添加到视图层次结构之前,容器视图控制器必须将子视图控制器与其自身关联。这允许 iOS 正确地将事件路由到子视图控制器以及这些控制器管理的视图。同样,当它从视图层次结构中删除子视图的根视图后,它应该断开该子视图控制器与其自身的连接。为了建立或破坏这些关联,您的容器调用基类定义的特定方法。这些方法不适合由容器类的客户端调用;它们只能由容器的实现使用来提供预期的遏制行为。

以下是您可能需要调用的基本方法:

添加ChildViewController:
从父视图控制器中删除
将移动ParentViewController:
didMove ParentViewController:

但它没有提供任何线索来说明它所谈论的“事件”或“预期遏制行为”是什么,或者为什么(甚至何时)调用这些方法是“必要的”。

Apple 文档的“自定义容器视图控制器”部分中的自定义容器视图控制器的示例都调用此方法,因此我认为它除了将子 ViewController 弹出到数组之外还有一些重要的用途,但我无法理解弄清楚那个目的是什么。这个方法有什么作用,为什么要调用它?


我认为一个例子胜过千言万语。

我正在开发一个图书馆应用程序,并希望显示一个漂亮的记事本视图,当用户想要添加注释时会出现该视图。

enter image description here

在尝试了一些解决方案之后,我最终发明了自己的自定义解决方案来显示记事本。因此,当我想显示记事本时,我创建了一个新实例NotepadViewController并将其根视图作为子视图添加到主视图中。到目前为止,一切都很好。

然后我注意到,在横向模式下,记事本图像部分隐藏在键盘下方。

enter image description here

所以我想改变记事本图像并将其向上移动。为此,我在中编写了正确的代码willAnimateRotationToInterfaceOrientation:duration:方法,但是当我运行应用程序时什么也没有发生!调试后我注意到没有一个UIViewController的旋转方法实际上是在NotepadViewController。仅调用主视图控制器中的那些方法。

为了解决这个问题,我需要调用所有方法NotepadViewController在主视图控制器中调用它们时手动进行。这很快就会使事情变得复杂,并在应用程序中不相关的组件之间创建额外的依赖关系。

那是过去的事了,在引入子视图控制器的概念之前。但现在,你只需要addChildViewController到主视图控制器,一切都会按预期工作,无需任何更多的手动工作。

Edit:有两类事件被转发到子视图控制器:

1-外观方法:

- viewWillAppear:
- viewDidAppear:
- viewWillDisappear:
- viewDidDisappear:

2- 旋转方法:

- willRotateToInterfaceOrientation:duration:
- willAnimateRotationToInterfaceOrientation:duration:
- didRotateFromInterfaceOrientation:

您还可以通过覆盖来控制要自动转发的事件类别shouldAutomaticallyForwardRotationMethods and shouldAutomaticallyForwardAppearanceMethods.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

addChildViewController 实际上做了什么? 的相关文章

  • iOS:如何在不降低 fps 的情况下播放音频?

    我正在使用 Sprite Kit 最好使用 Swift 库 为 iOS 9 开发游戏 目前 我正在使用 Singleton 在其中预加载音频文件 每个文件都连接到一个单独的 AVAudioPlayer 实例 这是一个简短的代码片段来了解这个
  • Swift 3:如何访问48字节CFData中matrix_float3x3的值?

    我正在尝试访问内在矩阵answer https stackoverflow com a 48159895 9296667 通过运行下面的命令 我能够得到一个 48 字节的任意对象 https developer apple com docu
  • NSCFData isRessized 崩溃?

    我目前在控制台中收到此崩溃日志 2011 08 23 19 18 40 064 App 1697 707 NSCFData isResizable unrecognized selector sent to instance 0x11f1c
  • mgwt - 以编程方式改变方向

    是否可以在 gwt mgwt 应用程序中更改强制执行特定的屏幕方向 可以说我希望用户始终以横向模式使用应用程序 这取决于 是作为phonegap应用程序 而不是在浏览器内部 如果您作为 Web 应用程序运行 则不需要t get any co
  • 如何在 iOS 中通过 Twitter API 获取用户电子邮件地址?

    我尝试了多个 SDK 但无法从任何资源获取电子邮件 ID 我努力了FHSTwitterEngine为此目的 但我没有得到解决方案 FHSTwitterEngine twitterEngine FHSTwitterEngine sharedE
  • Admob 广告无法快速显示

    您好 我正在尝试将 admob 广告添加到已使用 swift 上传到应用商店的应用程序中 我在 admob 中制作了一个应用程序并复制了 appid 和广告 id 并显示了各自的横幅广告和插页式广告 这里的问题是当我写这行时 request
  • iOS Safari Mobile 禁用上一个和下一个选择输入

    上周五我发现了关于此问题的类似问题 但似乎无法再次找到它 如果有人能指出我正确的方向 那就太好了 本质上我在一个页面上有多个选择菜单 第一个在加载时填充 第二个在第一个选择时填充 够简单的 但是 在 iOS 设备中 当您点击选择元素时 它会
  • AFNetworking XML 请求问题

    我在用着AFNetworking 2使用 JSON 响应 它工作正常 现在我必须将其转换为 XML 而不是使用 JSON 因为服务器响应是 XML 格式的 在我搜索之后 我找到了这段代码 但它不起作用 与 Charles 我发现请求是错误的
  • 如何正确创建迦太基 cartfile?

    我正在研究购物车文件 迫不及待地想 简单地创建一个购物车文件 就像所有说明所说的那样 只是 如何 简单地 创建一个 Cartfile 我创建了一个纯文本文档 将其命名为 cartfile 并在其中复制了一些依赖项 Ran carthage
  • 如何在 Swift 中将文件名与文件扩展名分开?

    给定包中文件的名称 我想将该文件加载到我的 Swift 应用程序中 所以我需要使用这个方法 let soundURL NSBundle mainBundle URLForResource fname withExtension ext 无论
  • 如何从 ContentView 外部显示 SwiftUI 警报?

    我正在构建 Swift 应用程序 并试图找出如何显示警报 我有一个单独的 swift 文件正在执行一些计算 并且在某些条件下我希望它向用户显示警报 基本上告诉他们出了问题 然而 我见过的大多数例子都要求警报在ContentView或以其他方
  • AppStore 提交:错误 ITMS-9000:“无效的捆绑结构 - 不允许二进制文件‘MyApp.app/BuildAgent’

    我陷入了以下错误 我根本不明白 错误 ITMS 9000 无效的捆绑结构 不允许使用二进制文件 MyApp app BuildAgent 您的应用程序可能只包含一个可执行文件 当我使用 Xcode 从 Archive 导出到 IPA 时 我
  • locationOfTouch 和 numberOfTouches

    你好 我有这个识别器 设置为 2 次触摸 但它只返回一个 而不是两个 CGPoint void gestureLoad UIGestureRecognizer recognizer recognizer UITapGestureRecogn
  • iOS 中 NSDecimalNumber 的小数分隔符错误

    我尝试通过以下方式输出具有正确的小数分隔符的十进制数的描述 NSString strValue 9 94300 NSDecimalNumber decimalNumber NSDecimalNumber decimalNumberWithS
  • CALayer边框奇怪问题

    我正在向 CALayer 添加边框 但有一些奇怪的行为 在我应用的边框之后出现模糊边框 参见屏幕截图 这是我的代码 void configureLabel self hidden YES self textAlignment NSTextA
  • dyld:无法加载插入的库

    当我尝试运行 UI 和单元测试时 出现异常 dyld 无法加载插入的库 private var containers Bundle Application AutoTestingApp app Frameworks IDEBundleInj
  • AVAssetExportSession 无法导出从 iCloud 下载的视频

    我正在尝试创建从用户相册中选择的视频的缩小版本 输出的最大尺寸为 720p 因此 在检索视频时 我使用 mediumQualityFormat as the deliveryMode 如果用户设备中不存在原始视频或其中等质量版本 这会导致
  • 如何向标准 UIButton 添加徽章? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 是否可以在标准中添加看起来标准的徽章UIButton 如果不支持半原生 那么实现此目的最简单的方法是什么 示例图片 这是 Sascha
  • 在实例化对象之前是否可以检查故事板中是否存在标识符?

    在我的代码中我有这一行 但我想知道是否有办法检查是否 一些控制器 在我将它与 一起使用之前就存在实例化ViewControllerWithIdentifier 方法 如果标识符不存在 则应用程序崩溃 如果没有好的方法 这并不是一个大问题 我
  • 在 Swift 中从 Parse 加载图像

    我成功地将数据从 Parse 提取到 swift 中 但我的图像似乎没有按照我的方式工作 在我的 cellForRowAtIndexPath 方法中 我执行以下操作 var event AnyObject eventContainerArr

随机推荐