从父 iOS 访问容器视图控制器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13279105/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 21:08:17  来源:igfitidea点击:

Access Container View Controller from Parent iOS

iosobjective-cswiftuiviewcontrolleruicontainerview

提问by Adam Waite

in iOS6 I noticed the new Container View but am not quite sure how to access it's controller from the containing view.

在 iOS6 中,我注意到了新的容器视图,但不太确定如何从包含视图访问它的控制器。

Scenario:

设想:

example

例子

I want to access the labels in Alert view controller from the view controller that houses the container view.

我想从包含容器视图的视图控制器访问警报视图控制器中的标签。

There's a segue between them, can I use that?

他们之间有一个segue,我可以使用它吗?

回答by Peter E

Yes, you can use the segue to get access the child view controller (and its view and subviews). Give the segue an identifier (such as alertview_embed), using the Attributes inspector in Storyboard. Then have the parent view controller (the one housing the container view) implement a method like this:

是的,您可以使用 segue 访问子视图控制器(及其视图和子视图)。alertview_embed使用 Storyboard 中的属性检查器为 segue 提供一个标识符(例如)。然后让父视图控制器(容纳容器视图的那个)实现一个这样的方法:

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
   NSString * segueName = segue.identifier;
   if ([segueName isEqualToString: @"alertview_embed"]) {
       AlertViewController * childViewController = (AlertViewController *) [segue destinationViewController];
       AlertView * alertView = childViewController.view;
       // do something with the AlertView's subviews here...
   }
}

回答by rdelmar

You can do that simply with self.childViewControllers.lastObject(assuming you only have one child, otherwise use objectAtIndex:).

您可以简单地使用self.childViewControllers.lastObject(假设您只有一个孩子,否则使用objectAtIndex:)。

回答by Sruit A.Suk

for Swift Programming

用于 Swift 编程

you can write like this

你可以这样写

var containerViewController: ExampleViewController?
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    // you can set this name in 'segue.embed' in storyboard
    if segue.identifier == "checkinPopupIdentifierInStoryBoard" {
        let connectContainerViewController = segue.destinationViewController as ExampleViewController
        containerViewController = connectContainerViewController
    }
}

回答by SimplGy

The prepareForSegueapproach works, but it relies on the segue identifier magic string. Maybe there's a better way.

prepareForSegue方法有效,但它依赖于 segue 标识符魔术字符串。也许有更好的方法。

If you know the class of the VC you're after, you can do this very neatly with a computed property:

如果你知道你所追求的 VC 的类,你可以使用计算属性非常巧妙地做到这一点:

var camperVan: CamperVanViewController? {
  return childViewControllers.flatMap({ 
var jobSummaryViewController: JobSummaryViewController {
    get {
        let ctrl = childViewControllers.first(where: { 
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
  switch segue.destination
  {
    case let aViewController as AViewController:
      self.aViewController = aViewController
    case let bViewController as BViewController:
      self.bViewController = bViewController
    default:
      return
  }
}
is JobSummaryViewController }) return ctrl as! JobSummaryViewController } }
as? CamperVanViewController }).first // This works because `flatMap` removes nils }

This relies on childViewControllers. While I agree it could be fragile to rely on the first one, naming the class you seek makes this seem quite solid.

这依赖于childViewControllers. 虽然我同意依赖第一个可能很脆弱,但命名您要寻找的类会使这看起来非常可靠。

回答by Robin Daugherty

An updated answer for Swift 3, using a computed property:

Swift 3 的更新答案,使用计算属性:

extension Array {
    func firstMatchingType<Type>() -> Type? {
        return first(where: { 
var viewControllerInContainer: YourViewControllerClass? {
    return childViewControllers.firstMatchingType()!
}
is Type }) as? Type } }

This only iterates the list of children until it reaches the first match.

这只会迭代子项列表,直到到达第一个匹配项。

回答by Gautam Jain

self.childViewControllersis more relevant when you need control from the parent. For instance, if the child controller is a table view and you want to reload it forcefully or change a property via a button tap or any other event on Parent View Controller, you can do it by accessing ChildViewController's instance and not via prepareForSegue. Both have their applications in different ways.

self.childViewControllers当您需要来自父级的控制时更相关。例如,如果子控制器是一个表视图,并且您想强制重新加载它或通过点击按钮或父视图控制器上的任何其他事件来更改属性,则可以通过访问 ChildViewController 的实例而不是通过 prepareForSegue 来完成。两者都有不同的应用方式。

回答by Joanna Carter

There is another way using Swift's switch statement on the type of the view controller :

在视图控制器的类型上使用 Swift 的 switch 语句还有另一种方法:

let viewController1 : OneViewController!
let viewController2 : TwoViewController!

// Safety handling of optional String
if let identifier: String = segue.identifier {

    switch identifier {

    case "segueName1":
        viewController1 = segue.destination as! OneViewController
        break

    case "segueName2":
        viewController2 = segue.destination as! TwoViewController
        break

    // ... More cases can be inserted here ...

    default:
        // A new segue is added in the storyboard but not yet including in this switch
        print("A case missing for segue identifier: \(identifier)")
        break
    }

} else {
    // Either the segue or the identifier is inaccessible 
    print("WARNING: identifier in segue is not accessible")
}

回答by Sunkas

With generic you can do some sweet things. Here is an extension to Array:

使用泛型你可以做一些甜蜜的事情。这是对 Array 的扩展:

- (IBAction)showCartItems:(id)sender{ 
  ListOfCartItemsViewController *listOfItemsVC=[self.storyboard instantiateViewControllerWithIdentifier:@"ListOfCartItemsViewController"];
  [self addChildViewController:listOfItemsVC];
 }

You can then do this in your viewController:

然后你可以在你的 viewController 中做到这一点:

##代码##

回答by Marco Leong

In case someone is looking for Swift 3.0,

如果有人正在寻找Swift 3.0

viewController1, viewController2and so on will then be accessible.

viewController1viewController2等将可以访问。

##代码##

回答by Mannam Brahmam

I use Code like:

我使用代码如下:

##代码##