currently I have a main Viewcontroller. Now I wish to implement the UItabbar to switch between few controllers. The problem now is this main view controller is just a normal UIviewcontroller, how can I implement the UItabbar and switch vc with selecting the tabbar item? Thanks all
if you are using storyboard
Get uitabbarcontroller-and link between it and the viewcontroller(by right click and drag to the view controller then select view controller from the drop menu)
Here is a tutorial
https://m.youtube.com/watch?v=nGx3MZM460c
If you want to create TabBar into your project you have to write it into AppDelegate:
let nav1 = UINavigationController(rootViewController: ViewController()) // ViewController inside TabBar
nav1.tabBarItem.title = "Title of VC"
nav1.tabBarItem.image = UIImage(named: "name_of_image")
let tabBarVC = UITabBarController()
tabBarVC.viewControllers = [nav1] // All VCs, what you want in TabBar
window?.rootViewController = tabBarVC
So I hope it helps you. If you write code programmatically without the storyboard.
through storyboard you can add tabBarcontroller to menuviewcontroller
intially my storyboard is like this
Drag from tabbarcontroller to menuviewcontroller you will get a pop up like this
Select relationship Segue "viewcontroller" and your storyboard will look like this
I don't know if its been made simpler since these answers were written. But it seems quite straightforward now - at least with Xcode 11.5.
So to add a tab bar to an existing Storyboard that's already got a UIViewController:
Drop a 'container view' onto your existing view. Pin it to the safe area. It doesn't need to cover the whole thing - eg. if you want a non-tabbed bit at the top. But it makes sense for it to extend it down to the bottom of the view - otherwise your tabs end up looking very non-standard!
When you dropped the container view, that will have created a new UIViewController for the container's contents. Delete it.
Now drop a Tab Bar Controller on the storyboard - eg. next to the main view controller's view. This creates three new view controllers - the tab bar controller, plus one for each of the two tab items it creates by default.
Now the crucial bit - we want to make the container view contain the tabbed views...
Select the Tab Bar Controller, select the Connections inspector, and drag from the 'Embed' presenting segue to the container on your main view.
Once you've dragged, a menu will pop up by the cursor with a single item - 'viewDidLoad'. Make sure you select this. It can be a bit fiddly to do for some reason - but once you select it correctly you'll see the link from 'Embed' to 'Container View viewDidLoad' in the Tab View Controller's connections inspector.
Voila! - you're done!
Related
The Problem
I'm relatively new to Swift and I'm trying to build an application that makes use of a UITabBarController.
What I'm trying to do is put a different navigation bar (or UINavigationItem) on each of the tabs in the UITabBarController.
For example, I want the UINavigationItem I set, with its bar button items, to appear on MyViewController instead of a back button to the previous view controller, such as shown on the image below.
The current layout on the Storyboard is as follows.
MyViewController on the sidebar:
What I've Tried
Someone suggested that I should embed each UIViewController (e.g. MyViewController) in a Navigation Controller. I've tried this and it doesn't work.
I've also tried to set the Top Bar to "None" in the Attributes tab of the options menu.
Thank you in advance for your help.
Here is how i did it,
UINavigationController -> UITabbarController
And then each "Tab" is in different Storyboard and every storyboard start with a "Navigation Controller". So yes every tab in different navigation controller this how you should do it.
Different storyboards because may be multiple people work on storyboard at same time.
Why TabbarController inside Navigationcontroller ?
I put the "TabbarController" inside "NavigationController" because some of the controllers i want them to be full screen, like hiding the "Tabbar" so for that i push them from main NavigationController.
//Out of context but may help you,
I have created an "Extension" of Navigation Controller to push a view controller on main navigation so that any of the tabbars (which are also inside navigation controllers) can easily use the extension to push any view controller if want to hide the tabbar.
I have the following storyboard with a segue to a storyboard reference:
The problem is that when I run the app, it doesn't show the icon or the title:
These are the item settings:
What am I missing?
Here's how to get the tab to show properly:
Put the first UIViewController that will be embedded in the tab in
the same storyboard as the UITabViewController.
Ctrl + Drag from the tab bar controller to the content view
controller to make the connection as per usual. This will
automatically add the UITabBarItem to the bottom of the content view
controller.
Select the content view controller.
Click the Editor menu and choose Refactor to Storyboard...
The UITabBarController tab will now point to the new storyboard reference...
... and the content view controller preserves the UITabBarItem from the tab bar relationship. It will appear normally in the app now.
You can modify image/title of the tab bar item in the initial view controller of the storyboard you are referring to. You just need to add a 'tab bar item' to the initial view controller and change its properties (title/image) accordingly.
Outline view of the root view controller in the referred storyboard
The modified tab bar item in the view controller
Note: the change will not be reflected on the tab bar in the main storyboard; you only see it in the referred storyboard and at runtime.
The problem is that in the target view controller, you don't have a UITabBarItem in the views hierarchy. The TabBarItem is related to the storyboard reference, but should be related to the View Controller.
Looks like a "bug" in Xcode...
To resolve this you can do the following:
Just create the segues from the UITabBarController to the Storyboard references.
You may configure the Tab Bar Items in the storyboard references, they don't do much more other than showing the tabs in the tab bar on the Storyboard, which is nice for development purposes.
If you now run the app, you will indeed notice that the tabs are missing.
To get the tabs to display in the running app as well, do this:
Go to the viewcontroller the storyboard reference is referencing to
Add a Tab Bar Item into this View Controller by dragging it from the Object Library into the View Controller
You will now see a tab bar with one single tab in the view controller
Configure the tab bar item to show the correct title and icon
Now run the app and you will now see your tabs.
I tried adding another tab bar, then added tab bar item, selected and image for it BUT Non of above seemed to work with my case ..
it was like this :
Then i compared it with VC that were working properly with TabBar icons..
later i found that my navigation items and tab bar items were not together :
Now its working :):)
After struggling with this problem for a few days I found this solution.
Double click the storyboard link, which will open the referenced storyboard. In the scene navigator, you can edit the bar item with a custom title and icon. Works in xCode 9.
Storyboard
Scene Navigator
I had this exact same issue and neither of the above answers worked in my case. I solved by setting my tab bar image in the image bar item section inside the storyboard's reference like shown in the attached image:
I made following in the storyboard and made class for each UINavigationController
and made following code in each UINavigationController class
override func viewDidLoad() {
super.viewDidLoad()
let someController = StoryboardManager.surveyStoryboard.instantiateViewControllerWithIdentifier("SomeController") as! SomeController
viewControllers = [someController]
// Do any additional setup after loading the view.
}
I did it in different way. My fourth tab was not showing. I just programmatically placed image on its place. You need to set its X,Y coordinates accordingly.
let imageName = "video"
let image = UIImage(named: imageName)
let imageView = UIImageView(image: image!)
imageView.frame = CGRect(x: view.frame.width - 80, y: view.frame.height-70, width: 50, height: 50)
view.addSubview(imageView)
Just add a Tab Bar Item in the "child" view controller:
this works for me
In the interface builder I have a UITabBarController and it is set as the initial view controller. From the tab bar controller, I have linked three independent ViewControllers; two UIViewController's and one UITableViewController. I have embedded all three of these views inside UINavigationController's as each of these views will eventually segue to a new view.
Interface Builder
Problem:
I now want to link one of the UIViewController's to the UITableViewController using a button to segue to the table view. This way I can pass information, i.e. func prepareForSegue(), to the table view. I want to maintain the tab bar controller at the bottom, however I do not want to have the ability to go back to the previous UIViewController from the current UITableViewController via a UIBarButtonItem at the the top of the view; That is what the tab bar at the bottom is for.
However every time I segue "Show" the table view (it is actually a segue to the table views navigation controller), the navigation bars at the top and the bottom of the table view disappear. Is there anyway to prevent this from happening?
I have also tried segue "Show" directly to the table view, in which case the tab bar is visible, but then it displays a "back" button at the top of the view to segue back to the sending UIViewController. I am hesitant about accepting a solution that would just hide the back button, because I feel I will run into problems down the road when I want to navigate to a detail view from the table view itself, since I would be bypassing the UITableViewController's UINavigationController.
Any solutions would be greatly appreciated. I have been trying to solve this problem for hours and I'm about to put my head through my computer screen. Also I thought about just using tabBarController?.selectedIndex on the button click to shift to the table view, and then passing the information using NSUserDefaults, but this is out of the question since I would be passing a custom object, and would have to encode and decode every custom field.
I you use a segue to get to it, as you say, you will still be using the UIViewController's UINavigationController which seems a bit messy. So I actually think selectedIndex is probably the best way to go as once you change to the UITableViewController you'll be in the correct navigation stack.
Instead of using NSUserDefaults, why not just reference the UITableView itself from the UIViewController, set the values you want, and then swap to it using self.tabBarController.selectedIndex.
So for your scenario above it, assuming the UITableViewContollrer is the third view in the UITabBarController, you would do something like the following:
Pass whatever you want into the UITabBarController by setting some pre-defined var in it. For example, if there was a String called saveMe in the UITableViewController, then do the following in the UIViewController:
let navController = self.tabBarController?.viewControllers![2] as! UINavigationController
let tableViewController = navController.viewControllers.first as! JarListTableViewController
tableViewController.saveMe = "Saved string here"
Swap to the UITableViewController using:
self.tabBarController?.selectedIndex = 2
The only issue with this is using selectedIndex won't perform a transition animation but not sure if you need this. This link could help if you do.
I have an iOS application with a Tab Bar, and two subview. My first view is a Table View.
So, I want to switch to the second view when I click on a cell of the first view, and keep the TabBar visible.
When I do that using "Show" segue in the storyboard, I lost the TabBar.
And when I do it in my TableViewController with the following code, the second view is not loading.
tabBarController.selectedViewController = mySecondViewController
That only select the second element in the TabBar, but didn't display him.
Anyone have a solution ?
try using index of UITabBar item to switch, like this:
tabBarController.selectedIndex = 1
The problem also may be because you try to set View to selectedViewController, where uiviewcontroller should be. It is hard to say, because of lack of information.
In the story board make sure you control drag from the tab bar controller to your view controller and click "Relationship Segue: View Controller"
I've fix my problem. I've originally put the line of code bellow on the viewDidLoad() of my controller :
tabBarController.selectedViewController = mySecondViewController
After moving this line in a different methode, call by a simple button, that worked...
I need to create a navigation in iOS app like following screenshot.
It contains a Tab Bar and a Side menu.
The problem is the right navigation menu button, should be visible in all tabs. Even all inner screens of each tab.
When user selects an option from side menu, it should be displayed on screen.
Now each tab should be accessible from each option item, and each option menu should be accessible in each tab. Its like a many-to-many relationship in DB.
How should I design it?
I have tried following so far.
Within each tab, there is a containerViewController. Which consists of my FrontViewController and SideMenuViewController.
When an option is selected from side menu, a message is passed to containerViewController which removes the old FrontViewController from view and adds new OptionViewController.
The menu button and navigation bar is added in containerViewController, so that if should be visible every time, at any screen.
Problems
Now facing some problems using this approach.
As the navigation bar is added in containerViewController. I have access it using parent property of my FrontViewController. Suppose if I need to use PushViewController in my FrontViewController, I have to use parent property. Like this
[self.parent.navigationController pushViewController:newVC animated:YES ];
[self.parent.navigationController popViewControllerAnimated:YES];
I have to use this approach within each tab. Means code is repeating 5 times.
Can anyone suggest a simple solution. Any help is appreciated.
You can try to use InteractiveSideMenu for your purpose. It supports interactive opening/closing menu and following customization:
Animation duration
Visible content width
Content scale
Using spring animation with params customization
Animation options like animation curve
You should use 3 basic ViewControllers for creating subclasses for implementing your side menu.
MenuContainerViewController is a host for menu and content views
MenuViewController is a container for menu view
MenuItemContentControlller is a container for content that corresponds menu item
Here is an example of setup Host controller.
import InteractiveSideMenu
class HostViewController: MenuContainerViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.menuViewController = self.storyboard!.instantiateViewController(withIdentifier: "NavigationMenu") as! MenuViewController
self.contentViewControllers = contentControllers()
self.selectContentViewController(contentViewControllers.first!)
}
private func contentControllers() -> [MenuItemContentViewController] {
//here is instantiation of content view controllers
}
}
I would think about subclassing UINavigationController and adding your button management logic there. When any view controller is pushed into the nav controller, set its bar button item.
The side menu shouldn't be inside each tab. Your root view controller should really control the main and side views and the main view has your tab controller which has a navigations controller as the root of each tab.
Now that the navigation bar doesn't need to be managed by a different container controller things become easier.
Bar button actions push up to the root view controller only, a reference to it can be set when the navigation controllers are created. Option selection would traverse root VC -> main (tab) VC -> selected tab nav controller -> push.
It could be easier to use a cocoapod for iOS side menus such as APMultiMenu. I've used it and it's simple to use and follow