简体   繁体   English

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

[英]Access Container View Controller from Parent iOS

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:设想:

例子

I want to access the labels in Alert view controller from the view controller that houses the container view.我想从包含容器视图的视图控制器访问 Alert 视图控制器中的标签。

There's a segue between them, can I use that?它们之间有一个 segue,我可以使用它吗?

Yes, you can use the segue to get access the child view controller (and its view and subviews).是的,您可以使用 segue 来访问子视图控制器(及其视图和子视图)。 Give the segue an identifier (such as alertview_embed ), using the Attributes inspector in Storyboard.使用 Storyboard 中的属性检查器为 segue 提供一个标识符(例如alertview_embed )。 Then have the parent view controller (the one housing the container view) implement a method like this:然后让父视图控制器(容纳容器视图的控制器)实现如下方法:

- (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...
   }
}

You can do that simply with self.childViewControllers.lastObject (assuming you only have one child, otherwise use objectAtIndex: ).您可以简单地使用self.childViewControllers.lastObject来做到这一点(假设您只有一个孩子,否则使用objectAtIndex: )。

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
    }
}

The prepareForSegue approach works, but it relies on the segue identifier magic string. prepareForSegue方法有效,但它依赖于 segue 标识符魔术字符串。 Maybe there's a better way.也许有更好的方法。

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({ $0 as? CamperVanViewController }).first
  // This works because `flatMap` removes nils
}

This relies on childViewControllers .这依赖于childViewControllers While I agree it could be fragile to rely on the first one, naming the class you seek makes this seem quite solid.虽然我同意依赖第一个可能很脆弱,但命名您要查找的类会使它看起来非常可靠。

An updated answer for Swift 3, using a computed property: Swift 3 的更新答案,使用计算属性:

var jobSummaryViewController: JobSummaryViewController {
    get {
        let ctrl = childViewControllers.first(where: { $0 is JobSummaryViewController })
        return ctrl as! JobSummaryViewController
    }
}

This only iterates the list of children until it reaches the first match.这只会迭代子列表,直到它到达第一个匹配项。

self.childViewControllers is more relevant when you need control from the parent. self.childViewControllers当您需要来自父级的控制时更为相关。 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.例如,如果子控制器是一个表视图,并且您想要强制重新加载它或通过点击按钮或父视图控制器上的任何其他事件更改属性,您可以通过访问 ChildViewController 的实例而不是通过 prepareForSegue 来完成。 Both have their applications in different ways.两者都有不同的应用。

There is another way using Swift's switch statement on the type of the view controller:还有另一种方法在视图控制器的类型上使用 Swift 的 switch 语句:

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
  }
}

I use Code like:我使用这样的代码:

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

In case someone is looking for Swift 3.0 ,如果有人正在寻找Swift 3.0

viewController1 , viewController2 and so on will then be accessible.然后可以访问viewController1viewController2等等。

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")
}

With generic you can do some sweet things.使用 generic 你可以做一些甜蜜的事情。 Here is an extension to Array:这是数组的扩展:

extension Array {
    func firstMatchingType<Type>() -> Type? {
        return first(where: { $0 is Type }) as? Type
    }
}

You can then do this in your viewController:然后,您可以在 viewController 中执行此操作:

var viewControllerInContainer: YourViewControllerClass? {
    return childViewControllers.firstMatchingType()!
}

you can write like this你可以这样写

- (IBAction)showDetail:(UIButton *)sender {  
            DetailViewController *detailVc = [self.childViewControllers firstObject];  
        detailVc.lable.text = sender.titleLabel.text;  
    }  
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何快速从父视图控制器访问容器视图中的数据? - How can I access data from a container view from the parent view controller in swift? 从父视图控制器在容器中设置tableViewCell - Setting tableViewCell in a container from a parent view controller 如果它们之间有容器视图,如何访问父视图控制器? - How to access parent view controller if there is container view inbetween? iOS-如何从容器视图访问变量并将其传递回视图控制器 - iOS - how to get access to a variable from the container view and pass it back to the view controller 在Swift 2中从父控制器访问Container视图控制器 - Accessing Container view controller from parent controller in Swift 2 访问容器视图控制器 - Access to container view controller 从容器视图调用父视图控制器功能 - Call parent View controller function from container view 将值从容器视图传递到父视图控制器 - Pass values from container view to parent view controller 如何从父视图控制器检测容器视图中的焦点UITextField - How to detect focused UITextField in Container view from Parent View Controller 从容器视图IOS访问和操作父视图控制器视图 - Accessing and manipulating parent view controllers views from a container view IOS
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM