Presenting child view controller inside UIPageController's current page - ios

I have a page view controller that transitions between view controllers using the normal UIPageViewController methods. Inside one of the presented view controllers (let's say the current view controller), I add a child view controller into a subview called containerView like so:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let child = storyboard.instantiateViewController(withIdentifier: "child")
self.addChildViewController(child)
child.view.frame = self.containerView.bounds
self.containerView.addSubview(child.view)
child.didMove(toParentViewController: self)
The view controller is presented inside the containerView, however it is only semi-interactive. For example, let's say the child view controller has a slider that updates a label with the slider's value. When sliding the slider, the slider will move visually inside the containerView, but won't update the label (the IBAction connected to the slider doesn't run). This behavior worked correctly when the view controller was presented normally (full screen using normal segueing).
Any ideas?

Seems as though something was going on with the storyboard view controllers, as I was able to remove the slider and add a new slider in and the functionality worked correctly inside the UIPageViewController page.

Maybe it is because you don't set constraints to child subview.
And when container view size changed - your child view is out of bounds.
You can check it is with View Debug feature in Xcode (when your app is in problem screen, you can capture all views (menu Debug->View debugging->Capture view hierarchy) and investigate what happens
child.view.frame = self.containerView.bounds
self.containerView.addSubview(child.view)
// need to add constraint, because if container view resized, child view frame not changed
child.view.autoresizinkMask = [.flexibleHeight, .flexibleWidth]
child.view.translatesAutoresizingMaskIntoConstraints = true
child.didMove(toParentViewController: self)

Related

Embed view controller inside container view based on selection from tableview

I'm trying to change the content of my container view based on what has been chosen from TableViewController and I'm out of an idea.
The structure in my storyboard looks like this:
Currently, my container view has embed segue with Table View and that's working great. Now after select something from Table View for example Map I want to display MapViewController inside container view and keep my header and footer. How can I do this?
First disable the segue form your container view to a DestinationViewController in your storyboard.
Now load your viewController object based on your previous tableViewController selection.
//this controller will be change on tableView selection make your own logic here.
let controller = storyboard!.instantiateViewController(withIdentifier: "Second")
addChildViewController(controller)
//Set this value false if you want to set Autolayout programmatically or set it true if you want to handle it with `frame`
controller.view.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(controller.view)
controller.didMove(toParentViewController: self)

Changing width of child view controller

I added child view controller to parent view controller programmatically in swift 3.0.
But I do not want the child view controller width as full screen, I want to customise the width and height of the child view controller. I tried to open the custom size child view controller, but it is not working.
// Here is my code
let secondViewController = storyboard.instantiateViewController(withIdentifier: storyBoardName)
secondViewController.modalPresentationStyle = UIModalPresentationStyle.custom
secondViewController.view.frame = CGRect(x: 0, y: 0, width: self.view.bounds.width-500, height: self.view.bounds.height)
self.present(secondViewController, animated: false, completion: nil)
Is there a way to achieve this?
In your code, you are not adding the secondViewController as childview controller. You are presenting that view controller. There is a difference.
You are trying to use UIModalPresentationStyle.custom to present viewcontroller using custom style. But using this custom style is not this trivial.
From documentation:
Creating a custom style involves
subclassing UIPresentationController and using its methods to animate
any custom view onto the screen and to set the size and position of
the presented view controller. The presentation controller also
handles any adaptations that occur because of changes to the presented
view controller’s traits
It tells you that you need to subclass UIPresentationController and subclass its method(with other methods) - (CGRect)frameOfPresentedViewInContainerView to set the frame of the presented viewcontroller.
More is explained in this link.
You can ofcourse achieve all this by actually adding a childviewcontroller.
Steps would be like this:
Create your child viewcontroller instance.
Set its view frame to whatever you want.
Add its view as a subview on to parent view controller's view using addSubview:
Call [addChildViewController] on parent viewcontrller (https://developer.apple.com/documentation/uikit/uiviewcontroller/1621394-addchildviewcontroller)
It depends on what you're trying to do, when I want to show some UI on top of another UIViewController I usually use a fullscreen view controller with self.modalPresentationStyle = .overFullScreen. Then I create another view which has the visible size I actually want to show to the user. This allows you to do pretty much anything you want.
But if you want an actual child viewcontroller, you need to use the appropriate functions for it.

Transparent Child View Controller's View

I am creating a child view controller in a parent view controller and presenting it with the code below -
self.addChildViewController(childVC)
childVC.view.frame = self.view.bounds
self.view.addSubview(childVC.view)
childVC.view.autoresizingMask = [.flexibleWidth,.flexibleHeight]
childVC.didMove(toParentViewController: baseVC)
The child view controller simply displays a 200 X 300 image view right in the middle. I want the child view controller to blur the parent view controller's view and display this opaque image view. However I can't seem to get it to show the underlying parent view controller's contents no matter what I do. I already tried the following in child view controller's viewDidLoad -
view.backgroundColor = UIColor.black.withAlphaComponent(0.5)
What am I missing here? Is there a better approach? The child view controller's purpose is to encapsulate the image preview logic by blurring the parent view controller's contents and display a UIImageView right in its view's center.
Try using ChildVC.backgroundColor = UIColor.black.withAlphaComponent(0.5). This code makes the child view appear semi transparent.
Hope this helps.
Create a new ViewController as a ChildViewController.
Give segue to ChildViewController from ParentViewController.
set following property
You have to select Presentation as Over current context
You can also change the Transition based on your requirement
See following image
Set background color of childViewController view as what you want and set its opacity 50% or 60% , whatever you want.
This will show parent view with blur effect.
My original solution -
view.backgroundColor = UIColor.black.withAlphaComponent(0.5)
is working. My parent view controller's view is white with very sparse detail so I assumed that the parent view isn't visible, silly overlook on my part.

Presentviewcontroller behind a view

I have a view setup where the my main view has a thin draggable view in it's hierarchy that resides at the bottom of the view.
Tapping on a particular button will present a view:
let productDetailsViewController: FMProductDetailsViewController = (UIStoryboard(name: "Catalogue", bundle: nil).instantiateViewControllerWithIdentifier("FMProductDetailsViewController") as? FMProductDetailsViewController)!
productDetailsViewController.selectedProduct = product
productDetailsViewController.delegate = self
productDetailsViewController.modalPresentationStyle = .OverCurrentContext
Is it possible to preset the view behind this bottom draggable view without having to manually present it by animating it myself?

How to set a view over a child view controller's view?

I am wondering if it is possible to set a view controller's view over one of its child view controller's view ?
Let's explain that with an example :
Let's say I have two UIViewControllers : parentVCand childVC. childVC is a child of parentVC.
Now, I have a UIButton ( called button ) which is a subview of parentVC.view.
I set childVC from parentVC like that :
self.addChildViewController(childVC)
childVC.didMoveToParentViewController(self)
childVC.view.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height
self.view.addSubview(childVC.view)
Now, I want button to show up even if childVC.view covers parentVC.view.
Do you guys think there's a way to do that ? I tried to play with button.layer.zPosition but I couldn't succeed.
Yes, you can, you just need to add the button to the view hierarchy or move the button up in the hierarchy after you add the child view controller.
yes you can do that first of all when you load a childview on a viewcontroller make a view like. There is a container on top covering almost 90% screen and at bottom there is a button,So when you load the view on container and sub view show's you on top if you tap a button then add a subview and bring that subview to front.

Resources