How to Use a 'Container View' in iOS

How to use container view programmatically

You need to set the frame and/or constraints on the loaded view:

override func viewDidLoad() {
super.viewDidLoad()

setUpViews()

let secondViewController = SecondViewController()

secondViewController.willMove(toParent: self)

containerView.addSubview(secondViewController.view)

// set the frame
secondViewController.view.frame = containerView.bounds

// enable auto-sizing (for example, if the device is rotated)
secondViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]

self.addChild(secondViewController)
secondViewController.didMove(toParent: self)

}

How can I access data from a container view from the parent view controller in swift?

To gain access to the container view from your parent, you will have to pass a reference from the container view to the parent and then use it in the parent view controller, there are many ways to do that and here is one of them.

In your viewDidAppear of InfoRegisterController which is the container view controller add the following code, this method will get a reference of InfoRegisterController into the parent to be used.

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)

let signUpControllerParent = self.parent as! SignUpController
signUpControllerParent.saveContrainerViewRefference(vc: self)

}

Now in SignUpController add a local variable for the coming reference to be saved and used later to get the data from the textfields.

var infoRegisterRefferenceVC : InfoRegisterController?

Add this method also in your parent SignUpController

func saveContrainerViewRefference(vc:InfoRegisterController){

self.infoRegisterRefferenceVC = vc

}

Now you can have access to all the textfields and the methods in the container view from the parent for example:

var fullNameTextField = self.infoRegisterRefferenceVC.fullName.text 

This should be it :)

Delegate using Container View in Swift

Looks like you defined the delegate, but have not set the delegate. This happens to me all the time.

how to load child view controllers or container views - Swift

As i understand there are 2 container views and you want to see the blue view when the segmented is first and you want to see the green view when the segmented is second if it is true the solution is like this;

You should init the uivew(hold on the ctrl and drag it to viewcontroller for both blue and green container view)(you need to add 2 different container view) and write

if segmented.selectedIndex == 0 { 

greenView.isHidden = true
blueView.isHidden = false

} else if segmented.selectedIndex == 1 {

greenView.isHidden = false
blueView.isHidden = true
}

From within a view controller in a container view, how do you access the view controller containing the container?

You can use the prepareForSeguemethod in Vc1 as an embed segue occurs when the ContainerViewController is made a child. you can pass self as an obj or store a reference to the child for later use.

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSString * segueName = segue.identifier;
if ([segueName isEqualToString: @"embedseg"]) {
UINavigationController * navViewController = (UINavigationController *) [segue destinationViewController];
Vc2 *detail=[navViewController viewControllers][0];
Vc2.parentController=self;
}
}

Edit: minor code fix

How to add a Container View programmatically

A storyboard "container view" is just a standard UIView object. There is no special "container view" type. In fact, if you look at the view hierarchy, you can see that the "container view" is a standard UIView:

container view

To achieve this programmatically, you employ "view controller containment":

  • Instantiate the child view controller by calling instantiateViewController(withIdentifier:) on the storyboard object.
  • Call addChild in your parent view controller.
  • Add the view controller's view to your view hierarchy with addSubview (and also set the frame or constraints as appropriate).
  • Call the didMove(toParent:) method on the child view controller, passing the reference to the parent view controller.

See Implementing a Container View Controller in the View Controller Programming Guide and the "Implementing a Container View Controller" section of the UIViewController Class Reference.


For example, in Swift 4.2 it might look like:

override func viewDidLoad() {
super.viewDidLoad()

let controller = storyboard!.instantiateViewController(withIdentifier: "Second")
addChild(controller)
controller.view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(controller.view)

NSLayoutConstraint.activate([
controller.view.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10),
controller.view.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10),
controller.view.topAnchor.constraint(equalTo: view.topAnchor, constant: 10),
controller.view.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -10)
])

controller.didMove(toParent: self)
}

Note, the above doesn't actually add a "container view" to the hierarchy. If you want to do that, you'd do something like:

override func viewDidLoad() {
super.viewDidLoad()

// add container

let containerView = UIView()
containerView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(containerView)
NSLayoutConstraint.activate([
containerView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10),
containerView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10),
containerView.topAnchor.constraint(equalTo: view.topAnchor, constant: 10),
containerView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -10),
])

// add child view controller view to container

let controller = storyboard!.instantiateViewController(withIdentifier: "Second")
addChild(controller)
controller.view.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(controller.view)

NSLayoutConstraint.activate([
controller.view.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
controller.view.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
controller.view.topAnchor.constraint(equalTo: containerView.topAnchor),
controller.view.bottomAnchor.constraint(equalTo: containerView.bottomAnchor)
])

controller.didMove(toParent: self)
}

This latter pattern is extremely useful if ever transitioning between different child view controllers and you just want to make sure one child's view is in the same location and the previous child's view (i.e. all the unique constraints for the placement are dictated by the container view, rather than needing to rebuild these constraints each time). But if just performing simple view containment, the need for this separate container view is less compelling.


In the examples above, I’m setting translatesAutosizingMaskIntoConstraints to false defining the constraints myself. You obviously can leave translatesAutosizingMaskIntoConstraints as true and set both the frame and the autosizingMask for the views you add, if you’d prefer.


See previous revisions of this answer for Swift 3 and Swift 2 renditions.



Related Topics



Leave a reply



Submit