【问题标题】:IBOutlet link to embedded container view controllerIBOutlet 链接到嵌入式容器视图控制器
【发布时间】:2012-09-22 12:02:54
【问题描述】:

我有一个复杂的 iPad 视图,我通过多个视图控制器进行管理。我之前(在 iOS6/Xcode 4.5 之前)通过在代码中分配我的视图控制器来做到这一点,并通过指向主视图的链接将各种视图连接到它们。

我想做的是使用新的 UIContainerView 容器视图将视图控制器嵌入情节提要文件中。我似乎无法将 IBOutlet 链接到嵌入式视图控制器到主控制器。

可以这样做吗?或者通过代码中的标签或其他东西来检索嵌入式控制器?

这个问题特别是关于使用容器视图

【问题讨论】:

  • 这是故事板的时代问题。令我惊讶的是,这方面没有 100 多个问题!

标签: ios storyboard xcode4.5


【解决方案1】:

Swift 版本的最高投票答案。多年后,Interface Builder 似乎仍然不支持将 IBOutlets 拖到嵌入式容器视图中。

改为在prepare(for:sender:)中设置网点:

@IBOutlet var someViewController: SomeViewController!

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "EmbedSomeViewController", let destination = segue.destination as? SomeViewController {
        someViewController = destination
    }
}

您还必须在 Storyboard 上设置 UIContainerView。 Xcode 会自动生成一个嵌入转场;设置segue的Identifier

【讨论】:

    【解决方案2】:

    注意事项

    在继续使用这个问题的答案之前,您可能希望反映嵌入式事物是否真的需要成为视图控制器。

    例如,如果您要嵌入 UICollectionViewController 子类,是否可以改为嵌入 UICollectionView 子类?或者,更好的是,您能否嵌入一个 UIView 子类,将 UICollectionView 隐藏在一个简单的 ViewModel 后面?

    在我目前正在处理的代码库中,我将两个视图控制器嵌入到另一个视图控制器中。两者都可以很容易地成为普通视图,然后可以更容易地绑定到情节提要中,而无需这些杂乱的代码。

    不幸的是,它们目前是视图控制器,我现在无法将它们简化为普通视图,所以必须这样做。

    背景

    我正在使用prepare(for segue:, sender:) 中的嵌入segue 的方法,正如Playful Geek 这里所建议的那样。

    我想展示我为此使用的 swift,因为它看起来相当整洁......

    class EditionLandingViewController: UIViewController {
        fileprivate var titlesView: SectionTitlesViewController!
        fileprivate var sectionsView: SectionsViewController!
    }
    
    //MARK:-
    
    extension EditionLandingViewController {
        private enum SegueId: String {
            case embedTitles
            case embedSections
        }
    
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            super.prepare(for: segue, sender: sender)
    
            guard
                let segueRawId = segue.identifier,
                let segueId = SegueId(rawValue: segueRawId)
                else { return }
    
            switch segueId {
            case .embedTitles:
                self.titlesView = segue.destination as! SectionTitlesViewController
    
            case .embedSections:
                self.sectionsView = segue.destination as! SectionsViewController
            }
        }
    }
    

    讨论

    我选择name segues as action methods

    对 segue 标识符使用 enum case 意味着您拥有编译器和工具,因此更难弄错 segue 名称。

    在这种情况下,将 segue id 保存在 extension 范围内的 private enum 中似乎是合适的,因为其他任何地方都不需要这些 segue(例如,它们不能是 performed)。

    我正在为嵌入式视图控制器使用隐式展开的类型,因为(在我的情况下)如果它们丢失,这是一个逻辑错误。

    同样,我也很乐意强制转换目标视图控制器类型。同样,如果这些类型不相同,那将是一个逻辑错误。

    【讨论】:

      【解决方案3】:

      这是另一个关于它的帖子:Access Container View Controller from Parent iOS

      他们建议在prepareForSegue 中保留引用或在self.childViewControllers 中搜索嵌入式viewController

      【讨论】:

        【解决方案4】:

        在某些情况下,另一种选择是使用-prepareForSegue:sender: 捕获嵌入式控制器。

        例如,如果我在 CustomContainerViewController 中嵌入了 UINavigationController,我可以在情节提要中将嵌入 segue 命名为 embedContentStack,并通过 CustomContainerViewController 捕获它

        - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
            if ([segue.identifier isEqualToString:@"embedContentStack"]) {
                // can't assign the view controller from an embed segue via the storyboard, so capture here
                _contentStack = (UINavigationController *)segue.destinationViewController;
            }
        }
        

        【讨论】:

        • 同意@prodos;这应该被接受,这是一种比查看子视图控制器数组更可靠的方法来捕获引用。
        【解决方案5】:

        我不确定您所说的“检索嵌入式控制器”是什么意思。当您想使用控制器时,您可以使用 UIStoryboard 方法 instantiateViewControllerWithIdentifier:,使用您在 IB 中提供给控制器的标识符。您还可以使用 performSegueWithIdentifier:sender: 方法(它也实例化了视图控制器)。您应该查看 Apple 文档中的“在您的应用程序中使用视图控制器”部分。它还提到了子视图控制器与容器控制器同时实例化的事实。

        编辑后:如果您将容器视图嵌入到另一个视图控制器中,则可以使用 self.childViewControllers 从包含控制器中引用该嵌入视图的控制器(这将是一个数组,因此如果只有一个,您可以获得它最后一个对象)。

        【讨论】:

        • 我正在执行 push segue 以到达“主视图控制器”。嵌入在该视图控制器中的是一个容器视图,指向另一个不同的视图控制器子类。在执行的某个时刻,我需要在主控制器和包含的视图控制器之间传递数据。您是否熟悉 XCode 4.5 中引入的容器视图元素?
        • @DanF,我不确定您所说的“容器视图元素”是什么意思。您是在谈论自定义容器控制器,还是其他?
        • 我说的是 XCode 4.5 界面构建器中称为“容器视图”的对象,它允许您将情节提要构建的视图控制器嵌入到另一个视图控制器中。如果你不知道那是什么,你就无法真正回答我的问题,除非你知道如何在故事板的两个不同场景中链接对象
        • 完美!正是我正在寻找的信息。如果您无法从包含视图中引用它们,容器视图对我来说似乎毫无用处。
        • 当有多个时你会怎么做??
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-12-20
        • 2013-09-28
        • 1970-01-01
        • 1970-01-01
        • 2017-12-13
        • 1970-01-01
        • 2015-10-23
        相关资源
        最近更新 更多