Embed view controller inside container view based on selection from tableview - ios

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)

Related

Swift ContainerView UI gesture not working

I have a View including a Container View which renders ViewControllers (Based on selected tab in TabBar)
When I try to click on the button (Which has a gesture/target event) it does not output anything in the console. UI Interaction is enabled on all views.
That's how I include the ViewController into the ViewContainer
let windowView = view.viewWithTag(1)
let contentView = view.viewWithTag(2)
let loginView = storyboard!.instantiateViewController(withIdentifier: "loginView")
currentView = loginView.view
contentView?.addSubview(loginView.view)
Is there anything I'm missing?
I got it working, I created two container views with their child views, and now show them based on the selected tab.

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.

Presenting child view controller inside UIPageController's current page

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)

Switch to another ContainerView from inside a ContainerView

I made an iOS app with Xcode and Swift.
One ViewController contains two ContainerViews. The user can switch between them with SegmentedControl.
But, how can I switch to the other ContainerView without the SegmentedControl, e.g. with a button?
Actually I have this code:
let vc : AnyObject! = self.storyboard!.instantiateViewControllerWithIdentifier("login")
self.showViewController(vc as! UIViewController, sender: vc)
This opens the other ContainerView, but as single VC, not inside the parent ViewController.
What can I do to reach the other ContainerView shown in the parent VC?
You must have to set the IBoutlets from ContainerViews viewControllers too to call them separately using uibuttons action.
assign same class to both parentViewcontroller and containerView using identity inspector see image.
connect IBOutlet as well like parentViewController see image
Now can access from class using uibutton action.
Iterate through your parent view controllers's child's like
parentViewController.childViewControllers.indexOf(self)
you got the index, means you can get the Controller then you can show it

How to change button name when cell selected in UITableView in swift?

I have two UIButton and when you click on each you will go to table view controller and there you can select something.
My question is how to change the button title on selection of any cell.
I want to replace button title with selected cell's name.
There are two ways to pass data back to the previous viewController.
1) Using Delegates, check this
2) Using Notifications, check this
Bind button in your cell as #IBOutlet
When cell selected delegate method tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath. Here you can get your cell with [tableView cellForRowAtIndexPath:indexPath]
Change your button's title [cell.yourButton setTitle...]
If you were to make your navigation controller into you root view controller and put the view controller you wish to access the buttons from as its top view controller then you could do the following when a cell is tapped:
if let topVC = navigationController?.topViewController as? MyButtonViewController {
topVC.button1Name.setTitle("New Title", forState: .Normal)
}
Then you can hide the navigation bar on the top view controller with the following:
override func viewWillAppear(animated: Bool) {
navigationController?.setNavigationBarHidden(true, animated: animated)
}
override func viewWillDisappear(animated: Bool) {
navigationController?.setNavigationBarHidden(false, animated: animated)
}
Instead of using two navigation controllers you can use a single NavC and then make your view controller with the two buttons as the root view controller. Then when the buttons are pressed you load the appropriate table view controller. Also if your table view controller has the same data source then you can use a single table view controller itself.
Then depending on which button is pressed you push the appropriate table view controller but in the prepareForSegue keep track of which button was pressed so that you can change its title when a cell is selected in the table view controller.
To pass the selected cell details from the table view controller you can make use of a delegate which your view controller can implement and the table view controller will call and pass the selected cell details.
So in short do this.
Make your navC as the initial view controller.
Make your view controller with the two buttons as the root view controller of the navC
In the IBAction of the two buttons store which button was pressed so that you will know which buttons's title has to be changed.
When you load table view controller set the view controller as a custom delegate.
In the language list table view controller's didSelectRowWithIndexPath use the delegate to pass the selected cell info and pop the view controller.
In the delegate method of the view controller change the button title that you have stored in step 3 to the selected cell's text.
I have another solution which I have uploaded here. It does not contain any custom view controllers except the ViewController that has the two buttons. It makes use of segues and unwind segues.
http://www.filedropper.com/twobuttonnavc

Resources