I have a viewcontroller lets say A that created with xib and I want to add navigationController to it .
View hierarchy :
UITabbarController -> NavigationController -> B Viewcontroller (A added tabbarcontroller in here when a button in B click)
I add A view to Tabbar in B Viewcontroller's button action like
tabBarController?.view.addSubview(A.view)
With this result , View A appears on Tabbar that what I want.
In A viewController there is a Tableview has some datas.When I click a row I want to push another Viewcontroller with self.navigationController.push(..) But I can't push anything because UITabbarController doesnt have a navigationController so I want to add NavigationController to A viewController . I searched lots of things but can't find any possible solution for it.
How can I achieve this?
Set the rootViewController of UINavigationController and add it to the view hierarchy.
let navigationController = UINavigationController(rootViewController: aViewController)
Also, to append a new view controller to the UITabBarController's viewControllers use:
tabBarController?.viewControllers?.append(navigationController)
Or:
tabBarController?.viewControllers?.insert(navigationController, at: 0)
Based on your view hierarchy
UITabbarController -> NavigationController -> B Viewcontroller
You must append ViewController not ViewController's view
func addMoreViewController() {
let aViewController = UINavigationController(rootViewController: aViewController)
self.viewControllers.append(aViewController)
}
Related
I currently have parental "menu" TableView with UINavigationBar and from each cell there is a segues by reference outlet to 3 similar Views with different information.
In each View there is a buttons to other 2 Views.
With every button's segue opens another View.
The problem:
From every View UINavigationBar's back button returns me to previous View but i tries to make back button to "menu".
Additional Bar Button Item and segue from it makes very close effect but segue animation is not like in UINavigationController.
How I could clean UINavigationBar transitions history in segue to initial View?
You can try pop to root view controller or You can edit navigation controller viewControllers property and remove/add some VC in between.
You can try Unwind Segue mechanism too.
Here are some methods(function) that navigation controller providing for pop operations. They are returning optional UIViewController (intance) from it’s navigation stack, that is popped.
open func popViewController(animated: Bool) -> UIViewController? // Returns the popped controller.
open func popToViewController(_ viewController: UIViewController, animated: Bool) -> [UIViewController]? // Pops view controllers until the one specified is on top. Returns the popped controllers.
open func popToRootViewController(animated: Bool) -> [UIViewController]?
Here is sample code as a solution to your query::
// if you want to back to root of your app
if let rootNavigationController = self.window?.rootViewController as? UINavigationController {
rootNavigationController.popToRootViewControllerAnimated(true)
}
// But if you want to back to root of your current navigation
if let viewcontroller = self.storyboard?.instantiateViewController(withIdentifier: "NewViewController") as? NewViewController { // or instantiate view controller using any other method
viewcontroller.navigationController?.popToRootViewControllerAnimated(true)
}
I have navigationController embedded VC(Viewcontroller) in storyboard 1 which is connected to storyboard reference of storyboard 2.
Now, I have VC2 which is again NavController Embedded in storyboard 2.
I am performing the following code :
let storyboard = UIStoryboard(name: "Settings", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "setEdit") as? EditProfile
navigationController?.pushViewController(vc!, animated: true)
settings is storyboard 2, setEdit is ID from navigationController of the destination VC.
When I execute this code, It doesnt perform the presentation of new controller. Also, I have a custom segue class that transitions VCs from Right to Left.
when I use :
present(vc!, animated: true, completion: nil)
It just pushes the VC from bottom to top.
Now I am totally out of Ideas.
My query is:
How can I exactly implement custom segue from one storyboard to another, having navigation bar at the top.
When you use UINavigationController the transition is showed as you said from right to left (push), when you present a view controller modally the presentation style and the transition style are different. Now you cannot connect two navigation controllers, so I suggest to connect directly the controller in the settings storyboard without embedding it in another navigation controller. In settings storyboard you have to set your EditProfileVC as initial view controller and check its identifier and then you can push it from your first storyboard.
Hi people and please help
Am not using interface builder.
In AppDelegate:
...
tabBarController.viewControllers = [tabOne, tabTwo, tabThree, tabFour]
window?.rootViewController = UINavigationController(rootViewController: tabBarController)
...
in tabOne witch is UIViewController, lazy load UITableView with custom cell and in that cell row I lazy load UICollectionView.
And i need to push in navigationController some viewController?
Thanks
Please make tabBarController as rootViewController of window
Then create 4 navigationControllers for 4 viewController (tabOne, tabTwo, tabThree, tabFour) of tabbarController.
Like these codes:
let viewControllers = [UINavigationController(rootViewController: tabOne),
UINavigationController(rootViewController: tabTwo),
UINavigationController(rootViewController: tabThree),
UINavigationController(rootViewController: tabFour)]
tabBarController.viewControllers = viewControllers
window?.rootViewController = tabBarController
TabbarController is a containerViewController, so:
you need to create 4 navigationController for 4 tabs, because they have the particular flows.
as your code, tabOne.navigationViewController is nil so you can't push other viewcontroller because your navigationController doesn't belong to tabOne, it belongs to tabBarController.
You have to take callback from Collection view cell to the controller or class(which contains the UICollectionView, I think in your case table view cell's .m file)
Then callback on the controller which contains the main table view.
Now you are on the root view controller of the tab.
Push the navigation controller from here (If you already have any navigation controller)
Your case:
TabBarViewController -> RootViewController(One out of four tab) ->
TableView -> TableViewCell -> UICollectionView -> UICollectionViewCell
Take the callback on RootViewController Then you can do anything.
Remember You should have navigation controller to push another controller.
I find solution.
In super class for ViewControllers, create function that push to navigation, and from View (Cell) need to delegate self, and call that function. Thanks to all who try to help
I am developing an iOS app in Swift 2.3, XCode 8.0. My app has 4 tabs and to each of the tabs - 4 different View Controllers are connected. Inside the 4 View Controllers I have embedded Navigation controllers.
My requirement is that when a user selects tab 1 -> goes to ViewController 1 -> Next the user can go to 2nd View Controller as there is a navigation controller.
But when the user selects the second tab and then comes back to the first tab, instead of showing the first View Controller that is directly attached to tab 1, the View Controller that was last opened with the back button is shown.
How can I move directly move to the View Controller attached to the first tab?
The embedded navigation controller should automatically keep track of the stack for you regardless of which tab the user is in with the tab bar controller. Make sure each tab has its own navigation controller embedded into it instead of having the entire tab bar controller embedded in one navigation controller.
For example, if you implemented this programmatically:
let viewController1 = UIViewController()
let navigationController1 = UINavigationController()
navigationController1.setViewControllers([viewController1], animated: true)
let viewController2 = UIViewController()
let tabBarController1 = UITabBarController()
tabBarController1.setViewControllers([navigationController1, viewController2], animated: true)
Here the navigationController1 will keep track of which viewController is on top of the stack regardless of where the user is in the tab bar controller.
Thanks, I found the solution -
This works for me -
In my main tab bar viewController, I made it a delegate of both UITabBarController, UITabBarControllerDelegate and then implemented the didSelectViewController method of UITabBarControllerDelegate as below -
func tabBarController(tabBarController: UITabBarController, didSelectViewController viewController: UIViewController) {
let index : Int = (tabBarController.viewControllers?.indexOf(viewController))!
let navigationController = viewController as? UINavigationController
navigationController?.popToRootViewControllerAnimated(false)
}
I am trying to display a fix navigation bar for my UiTableViewController, I have a first ViewController and when I click on it, this will open my UITableViewController Here is the code of the click :
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("MyTableViewController") as! MyTableViewController
vc.myObject = object // I pass some data
presentViewController(vc, animated: true, completion: nil)
the UItableView is correctly display but not navigation bar appear, if I add one, the navigation bar scroll with the table view and I don't want this behavior.
I tried this without success :
Go to the Editor menu, and click on the Embed In submenu, and choose
Navigation Controller
And tried to change some settings here :
Actually, in your case you want to show navigation and for navigation you have to push your view controller to a UINavigationController thats why the solution is :
let vc = storyboard.instantiateViewControllerWithIdentifier("MyTableViewController") as! MyTableViewController
vc.myObject = object // I pass some data
self.navigationController?.pushViewController(vc, animated: true)
presentViewController offers a mechanism to display a modal view controller; i.e., a view controller that will take full control of your UI by being superimposed on top of a parent controller & establish a parent child relation b/w presenting & presented view controllers.
where as
pushViewController offers a much more flexible navigation process where you can push & pop a new controller to UINavigationController, so to go back to the previous one, in a ordered way. Imagine that controllers in a navigation controller will just build a sequence from left to right like building a stack of view controllers stacking upon each other.
Do it this way:
let vc = storyboard.instantiateViewControllerWithIdentifier("MyTableViewController") as! MyTableViewController
vc.myObject = object // I pass some data
self.navigationController?.pushViewController(vc, animated: true)