Present view controller in a container view at collection view didSelectItemAtIndexPath swift - ios

I am trying to present a view controller in a container view when i select a cell from a collection view. The problem is that I can't seem to understand how to present it in the container below the collection view.
I tried:
if (indexPath.row == 0){
// Presenting first view controller
let detailedViewController: ViewController =
self.storyboard!.instantiateViewControllerWithIdentifier("ViewController") as! ViewController
self.presentViewController(detailedViewController, animated: true, completion: nil)
How can I make it go to the container instead of presenting the whole view controller.
Thanks in advance!

self.addChildViewController(detailedViewController)
containerView.addSubview(detailedViewController.view)

Swift 5.0 Use this functions to add and remove child VC:
private func add(asChildViewController viewController: UIViewController, childFrame:CGRect) {
// Add Child View Controller
addChild(viewController)
// Add Child View as Subview
view.addSubview(viewController.view)
// Configure Child View
viewController.view.frame = childFrame
viewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
// Notify Child View Controller
viewController.didMove(toParent: self)
}
private func remove(asChildViewController viewController: UIViewController) {
// Notify Child View Controller
viewController.willMove(toParent: nil)
// Remove Child View From Superview
viewController.view.removeFromSuperview()
// Notify Child View Controller
viewController.removeFromParent()
}
adopted from here

Related

Swift - Pass data from Child View to Parent View

I want to pass my data from child view controller to parent view controller.
I'm just moving the child view to the top of the parent view, here is my code:
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let toChildView = storyBoard.instantiateViewController(identifier: "toChildView")
// show child view
self.addChild(toChildView)
toChildView.willMove(toParent: self)
toChildView.view.frame = self.view.bounds
self.view.addSubview(toChildView.view)
toChildView.didMove(toParent: self)
Here is the delegate:
protocol DataDelegate {
func printTextField(string: String)
}
I added variable delegate to my Child View
var delegate: DataDelegate?
And send the data to Parent View
#IBAction func btnSend(_ sender: Any) {
delegate?.printTextField(string: textField.text)
}
And close the Child View, like:
#IBAction func btnClose(_ sender: Any) {
// back to parent view
self.willMove(toParent: nil)
self.view.removeFromSuperview()
self.removeFromParent()
}
Calling the DataDelegate to Parent View
class ParentView: UIViewController, DataDelegate {
func printTextField(string: String) {
print(string)
}
}
Im planning to pass the data of my text field from child view to parent view, I try this codes:
https://jamesrochabrun.medium.com/implementing-delegates-in-swift-step-by-step-d3211cbac3ef
https://www.youtube.com/watch?v=aAmvQU9HccA&t=438s
but it didn't work, any help thanks :)
EDITED: Added my delegate implementation code...
So as per the code you have done with declaration but not initialized the delegate. So go to you ParentView and assign the delegate in viewDidLoad or in the function where you prepare to move on child like:-
toChildView.delegate = self
And try again. :-)
you will not get delegate property in parent view as it is member of childView. You can do following
self.addChild(toChildView)
toChildView.delegate = self

How to pass data to a embedded UIViewController in side a UIView - Swift 5

There's a view controller B. So, have embedded B as child view controller in viewController A in a UIView. Now, need to call a api in child view controller B when it is added as a child. So, need to set a check when added B as child only then this api need to be hit. Kindly help in this.
Below is the code, how i embedded B as child View in A viewController:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vcController: UIViewController = storyboard.instantiateViewController(withIdentifier: "BNameViewController") as! BNameViewController
//add as a childviewcontroller
addChild(vcController)
// Add the child's View as a subview
viewBList.addSubview(vcController.view)
vcController.view.frame = viewBList.bounds
vcController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
// tell the childviewcontroller it's contained in it's parent
vcController.didMove(toParent: self)
viewBList is the UIView in View controller A.
So, now need in this case an api to be called in VC B not when we navigate to B from any other VC. I tried passing a bool or string by declaring same in VC B and the pass value from A, that doesn't work. Please guide. Hope i made my question clear, please feel free to ask if any doubt.
There are so many ways to do this, When you are navigating to view controller B from some other view controller then you have navigationController property not nil.
In that case you can check like that
override func viewDidLoad(animated: Bool) {
super.viewDidLoad(animated: animated)
//If navigating from some view controller then
if self.navigationController != nil {
//Code here for case, when you are navigating from some one
}
//View controller is child of someone
if (self.navigationController == nil || self.presentingViewController == nil || self.parent != nil ) {
//This is your case,
// hit api here
}
}

viewController.view not getting added to custom view inside Parent View Controller

I would like to add a childViewController into a custom UIView part of a parentViewController. However, if I am doing self.customView.addSubview(childViewController.view) I cannot see the childViewController.view as it doesn't get added. In contrast, if I do self.view.addSubview(childViewController.view) it all works well. Can someone explain why this is happening? I really need to add childViewController.view as subview of the customView and not as part of the self.view.
if let childViewController = self.storyboard?.instantiateViewController(withIdentifier: "ChildVC") as UIViewController? {
self.addChildViewController(childViewController)
childViewController.view.frame = customView.bounds
self.customView.addSubview(childViewController.view)
childViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
childViewController.didMove(toParentViewController: self)
childViewController.view.frame = CGRect(x: customView.frame.origin.x,
y: customView.frame.origin.y,
width: customView.frame.width,
height: customView.frame.height)
}
How about using a Container view from Object Library (place from where we drag table view, textView and all UI components onto our storyboard). which is
Container view define a region of view controller that include
a child view controller
When you take Container view from object library in your desired
ViewController on storyBoard.
it automatically gives you a another view controller attached to your view controller with a segue.
you just need to override this segue code and that dragged container view will work as a child view controller for you it did load will call automatically.
just Override this is your parent view Controller
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let identifier = segue.identifier {
switch identifier {
case "SegueIndetifierName":
(segue.destination as? YourChildViewController)?.parentViewControllerObject = self
default:
break
}
}
}
NOTE: declare parentView controller object in your child view controller like this
weak var parentViewControllerObject: ParentViewController!
to uniquely identify the relation ship between child and parent. and rest your work will be done automatically.
You can check the Sample Working project to add Subviews
Link https://github.com/RockinGarg/Container_Views.git
Required Code:
Class Object to be added as Subview
private lazy var FirstObject: firstVC =
{
// Instantiate View Controller
let viewController = self.storyboard?.instantiateViewController(withIdentifier: "firstVC") as! firstVC
// Add View Controller as Child View Controller
self.addChildViewController(viewController)
return viewController
}()
Add in ParentView as Subview
private func add(asChildViewController viewController: UIViewController)
{
// Configure Child View
viewController.view.frame = CGRect(x: 0, y: 0, width: self.firstContainer.frame.size.width, height: self.firstContainer.frame.size.height)
// Add Child View Controller
addChildViewController(viewController)
viewController.view.translatesAutoresizingMaskIntoConstraints = true
// Add Child View as Subview
firstContainer.addSubview(viewController.view)
// Notify Child View Controller
viewController.didMove(toParentViewController: self)
}
Where : -
firstContainer is the parent view In which subview is to be added
viewController class object whose view is to be added as Subview
Note- This can be used in containerViews as well as Normal UIView too for adding a Controller as Subview

Is it possible to set a view over a modal view?

In this ViewController, it will present a modal view.
After the modal view presented, how to set the following views to over the modal view?
The first view is UIImageView in current ViewController.
The second view is another modal view, in this example, modalViewController2 will display under the first one.
class ViewController: UIViewController {
#IBOutlet weak var img: UIImageView!
override func viewDidAppear() {
super.viewDidAppear()
self.modalViewController = self.storyboard!.instantiateViewController(withIdentifier: "modal") as! ModalViewController
self.modalViewController!.modalPresentationStyle = .overCurrentContext
self.present(self.modalViewController!, animated: true, completion: nil)
self.modalViewController2 = self.storyboard!.instantiateViewController(withIdentifier: "modal2") as! ModalViewController2
self.modalViewController2!.modalPresentationStyle = .overCurrentContext
self.present(self.modalViewController2!, animated: true, completion: nil)
}
}
First presenting a view controller should be in viewDidAppear as in viewDidLoad view's hierarchy is not yet complete , second you can't present 2 modal VCs at the same time , better way to make only one modal VC and construct it with say 2 views and manage hide/show for each one according to your need

Simple, custom navigation between 4 view controllers

I have UIScrollView which contains many following Subscription View Controllers. Each Subscription View Controller contains Container View Controller.
The target is to do a simple navigation between 4 Views Controllers at the right side.
Navigation logic:
On viewDidLoad show first or second View Controller in Container
When the user press a button on View Controller show the third View Controller in the Container
I tried to use Segues but this didn't work. The way to instantiate VCs to
Subscription View Controller is not good idea.
Use this code to switch the container views view...
#IBOutlet weak var container: UIView!
var currentViewController:UIViewController?
//put the view did load method here.
#IBAction func buttonPressed() {
//the storyboard file that the view is in.
let storyboard:UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
// the container view you want to switch to.
self.currentViewController = storyboard.instantiateViewControllerWithIdentifier("containerViewStoryboardID") as? UIViewController
//switch the container view.
self.addChildViewController(self.currentViewController!)
self.container.addSubview(self.currentViewController!.view)
self.currentViewController!.didMoveToParentViewController(self)
}
The simplest way I found is to create custom Segue.
Creating custom UIStoryboardSegue
Go to File -> New -> File... and choose Cocoa Class
Create a new class from UIStoryboardSegue
Configurate MySegue
import UIKit
class NewSegue: UIStoryboardSegue {
//Call when performSegueWithIdentifier() called
override func perform() {
//ViewController segue FROM
var sourceViewController: UIViewController = self.sourceViewController as! UIViewController
//ViewController segue TO
var destinationViewController: UIViewController = self.destinationViewController as! UIViewController
//Parent ViewController - ContainerViewController
var containerViewController: UIViewController = sourceViewController.parentViewController!
//Setting destinationViewController
containerViewController.addChildViewController(destinationViewController)
destinationViewController.view.frame = sourceViewController.view.frame
sourceViewController.willMoveToParentViewController(nil)
//Do animation
containerViewController.transitionFromViewController(sourceViewController,
toViewController: destinationViewController,
duration: 0.3,
options: UIViewAnimationOptions.TransitionCrossDissolve,
animations: nil, completion: { finished in
//Delete sourceViewController
sourceViewController.removeFromParentViewController()
//Show destinationViewController
destinationViewController.didMoveToParentViewController(containerViewController)
})
}
}
Go to your Storyboard file and do control drag from ContainerViewController to needed Controller and choose Custom in context menu
3.Click on created segue and configure them
Now you can call performSegueWithIdentifier("SugueID", sender: self) in your ContainerViewController or in other ViewController

Resources