I've been having a weird issue with the UITabBarController. Here it is:
I created a new Single View application
I dragged and dropped Tab Bar Controller on to the storyboard which has two initial view controllers.
I created two classes for those two view controllers.
I dragged another view controller on to the storyboard and connected the UITabBar to this new view controller. So now the tab controller shows three tabs.
So the issue is sometimes the tabbar doesnt show the third tab at all. And sometimes it shows. I've no freakin idea why this is happening. Can anyone please me with this.
Anand.
I found that I had to set the title manually after creation for the tab to show up in the TabBarController. I still have no idea why...
let salesController = SalesController(nibName: nil, bundle: nil)
let orderReviewController = OrderReviewController(nibName: nil, bundle: nil)
let accountController = AccountController()
// need to set the title here instead of viewDidLoad() otherwise tab doesn't show up...wtf?
accountController.title = "Account"
viewControllers = [salesController, orderReviewController, accountController]
When you are creating Tabbar app using Single View application, create tabbar like this:
Select single view goto Menu Editor-->Embed In --> Select Tab Bar Controller.
Then drag drop your other two viewController.
Create a realetionShip Segue with viewController clean project it should be working.
Related
I have an application that is supporting only ios7+ The navbar setup is using the new 64px high bar that appears beneath the status bar. Here is what it looks like when the app launches:
If I do any sort of "presentViewController", when i dismiss the view the navbar shifts back to 44px height and still appears underneath the status bar which in-turn makes all the contents of the view also shift up. Here is what that looks like:
It doesn't matter if I am presenting one of my own views or if I simply present a UIImagePickerView, any sort of slide up modal via the navigation controller breaks the navbar setup. Any ideas on how to fix this?
A few notes:
in plist: "View controller-based status bar appearance" is set to "NO"
navbar configured with self.navController.navigationBar.translucent = NO;
I am using .xib NOT Storyboards
UPDATE:
I have the navigation controller inside of a PKRevealController (https://github.com/pkluz/PKRevealController). Taking the reveal controller out and just adding the nav controller to the window itself fixes the issue... why would the reveal controller cause it to behave differently?
SOLUTION:
It turned out that the PKRevealController library was causing the issue. I reworked how it was set up in the AppDelegate and that solved the problem, although it's sorta of "hacky". I put my "before" and "after" configurations below:
the initial setup was :
configure PKRevealController
configure NavController and add rootView
set pkreveal front view = navController
add reveal controller to window as windows root view
the fix is
create a containing NavController
do stpes 1-3 above
add pkrevealcontroller to the containing navController
set containing nav controller nav bar to hidden
add containing nav controller to window as root view
If its navigationcontroller than you can use this inside every viewcontroller's viewdidload:
if ([self respondsToSelector:#selector(edgesForExtendedLayout)]) {
self.edgesForExtendedLayout = UIRectEdgeNone;
}
I had the same problem, but solved very easily by just setting the UINavigationBar Y-position to 20px and not to 0px. Then you have to assign the UINavigationBarDelegate to your ViewController:
[_navigationBar setDelegate:self];
Furthermore you have to add this method to your ViewController, which will be called because of the Delegate assignment:
-(UIBarPosition)positionForBar:(id<UIBarPositioning>)bar
{
return UIBarPositionTopAttached;
}
On my firstViewController I have a tabbar that contains my firstViewController and a helpViewController.
When I click on a button from the FirstViewController, I push a NewViewController. But, when this view is pushed, I want to change the content from the TabBarController to display other ViewControllers, like infoViewController, optionViewController and NewViewController. Is that possible?
The First Image represents my application. The FirstViewController has a button that will push the NewViewController. When the user clicks this button, I want that my app shows what is in the second image. Is possible?
Yes, this is possible (I just did a proof of concept in Xcode). Assuming that you are using storyboarding, you need to make your initial view controller a UINavigationController otherwise you won't be able to use the push segues. Then, make the first UITabBarViewController the root view controller of the navigation controller. Put an entirely new UITabBarController into the storyboard, and then put a UIButton into the firstViewController and link it via a push segue to the new (second) UITabBarController.
When you tap the button the old tab bar will slide off, and the new one will slide on.
Here's an example of how it all looks:
!!This app uses navigationController and TabBarController!!
Using the storyboard I saw each piece of the app, then I had the Idea: Insted of pushing the NewViewController, how about push a tabBarController? When the user clicks the button, the app will push the tabBarController with 2 TabController`s.
Just add New File to your project, sub classed UITabBarController. Then add this code to the init method of your tabBarController: self.hidesBottonBarWhenPushed = YES;
On ViewDidLoad just alloc and init what views you want to display on the tabBar and
self setViewControllers:[NSArray arrayWithObjects: vc1, vc2, vc3, nil]];
Working fine here :D
You can nest TabBarControllers. But that would look strange. And the first TabBar wouldn't be changed. Pushing a TabBarController into a TabBarController is not possible because TabBarController does not support pushViewController. Thats only possible with a NavigationController.
Anyhow you can change the content of the TabBar completely programatically.
I created a new navigation controller in my storyboard (not programmatically!) and set it to be "Root View Controller" to a regular UIViewController and added a button in it which says- forward to the next view controller (this second view controller is a view controller which I want that will have a back button to link to the initial view controller).
Now, whenever I try to link the button to the next view controller- "Pushing a navigation controller is not supported".
Help me please, and thanks
EDIT:
I accidentally subclassed UINavigationController, and not UIViewController in my class.
Thank you anyway.
I've tried this and have no problems, its all done in IB with no additional code required ...
Start a new project, "Single View Application" using story boards
Select storyboard and delete the views its produced.
Drag on a new Navigation Controller (it will bring a table view with it)
Delete the table and the table view controller, so you are just left with the Navigation Controller
Drag on a normal view controller
Right Click and drag from the Navigation controller to the new View and choose "Relationship - Root View Controller"
Drag a "Bar Button Item" on to the Navbar which should be visible on the top of your ViewController, you can rename this Forward if you wish.
Now drag on another view controller which is the one your "Forward" button will push in to view.
Right Click and drag from the bar button to the 2nd View Controller, and choose "Push"
Run the project and you will get a Single view with a Navbar and your button, clicking your button will Push the other view and give you a Back Button to return to the first View Controller. I'll try and post a picture of my storyboard if it helps.
Plasma
I had the same trouble. I wanted to have a navigation controller on each storyboard, so that each could run independently, be individually debugged, and so that the look would be right with the navigation bar.
Using other approaches, I found the UINavigationController would be retained from the original storyboard -- which I didn't want -- or I'd get errors.
Using the AppDelegate in your view controller to set the rootViewController worked for me (borrowing segue naming conventions from Segue to another storyboard?):
- (void)showStartupNavigationController {
NSLog(#"-- Loading storyboard --");
//Get the storyboard from the main bundle.
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"Startup" bundle:nil];
//The navigation controller, not the view controller, is marked as the initial scene.
UINavigationController *theInitialViewController = [storyBoard instantiateInitialViewController];
NSLog(#"-- Loading storyboard -- Nav controller: %#", theInitialViewController);
//Remove the current navigation controller.
[self.navigationController.view removeFromSuperview];
UIWindow *window = [(AppDelegate *)[[UIApplication sharedApplication] delegate] window];
window.rootViewController = theInitialViewController;
To swap views Programatically you would need to select the segue and give it an Identifier like "PushView" then call it like this ....
[self performSegueWithIdentifier:#"PushView" sender:self];
That will programatically do the same as clicking the forward button. I've created you an example project with the code discussed above. Has an -(IBAction) with code in you can use for programatially changing the view.
PushView.zip
I also wanted to do this, present a screen (that had an embedded navigation controller) when the user pushes a button.
At my first attempt, I connected the segue from the button in the fist screen to the Navigation Controller, and the app was crashing with this error "Pushing a navigation controller is not supported".
This is the solution I found:
Select the segue from the button in the first screen to the navigation controller.
If it had an identifier, copy its name. Then delete that segue.
Then create a new segue by CTRL-clicking the button in the first view controller and dragging to the VIEW CONTROLLER YOU WANT TO PRESENT (not to the Navigation Controller that is pointing at it), and select Push in the small pop up window.
Then click the icon in the middle of the segue and paste the name you copied in the first step as an identifier for it.
IB is going to give you a warning "Scene is unreachable due to lack of entry points and does not have an identifier for runtime access via -instantiateViewControllerWithIdentifier:." Don't worry, it works perfectly.
If you want to customize the string that is shown as the Back button to return, you can add this line in the viewDidLoad method OF THE VIEW CONTROLLER THAT IS BEING SHOWED AFTER THE BUTTON IS PRESSED, that is the Child view controller.
(replace "Settings" with the name you need)
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationController.navigationBar.topItem.title = #"Settings";
...
}
I'm trying to connect Tab Bar Controller to existing part of my app, but when I do that it's "malfunctioning".
However when I run Tab Bar Controller part standalone as initial view controller it works properly like in the image below :
This is how app looks when it is run(correct behavior) :
However when I go to this tab bar controller from my main app this is how it looks like this:
My main app looks like this :
Scroll View contains
UIView 1
UIView 2
UIView 3
UIView x
Each view does something not related to this tab bar controller. Only one view view x tries to "visit" tab bar controller and display some data there, but it's not. Any ideas?
I have this tab bar controller identifier set to test, and I here is how I do that from my view x :
UITabBarController *newViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"test"];
[self.view addSubview:newViewController.view];
EDIT :
Entire app :
I'm creating views programatically. That's why I don't have any relationships/segues to the tab bar controller.
SOLUTION :
Change :
UITabBarController *newViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"test"];
[self.view addSubview:newViewController.view];
To :
UITabBarController *newViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"test"];
[self addChildViewController:newViewController];
[self.view addSubview:newViewController.view];
You need to set a root viewController to the navigation Controller
Just don't do this. From the Apple UITabBarController referenece
Because the UITabBarController class inherits from the UIViewController class, tab bar controllers have their own view that is accessible through the view property. When deploying a tab bar interface, you must install this view as the root of your window. Unlike other view controllers, a tab bar interface should never be installed as a child of another view controller.
As I understand it means you must use UITabBarController only as a root view controller of the window. But you can alway use a general UIViewController and add UITabBar there.
(The view offset problem you've met is possible to be fixed, it will not follow the Apple guidelines however and not advised).
I drag out a toolbaritem in storyboard and set it on my nav controller, but when I run my code it's not there, is there something I'm missing?
EDIT:
Tried setting it in code as well in my viewDidLoad method:
UIBarButtonItem *rightBarButton = [[UIBarButtonItem alloc] initWithTitle:#"Map" style:UIBarButtonItemStyleBordered target:self action:#selector(viewMap)];
self.navigationItem.rightBarButtonItem = rightBarButton;
Won't work either.
Here's how it's set up in my storyboard:
UPDATE:
Just found my problem. In my controller code when I update it's contents I change the right bar button item for a spinner and never set it back to what it had before.
UINavigationController already has a toolbar built in. It has a property toolBarHidden which is set to YES by default, which is why it is not normally seen. If you are using storyboard you can easily make the built-in bottom toolbar visible by checking the checkbox "Shows Toolbar" in the inspector when the Navigation Controller is selected.
See the UINavigationController documentation here for more details.
EDIT:
Ok, it sounds like what you are trying to do is add a right button to your view controller's UINavigationItem. To do this in storyboard, drag a "Bar Button Item" from the Objects Library onto the Navigation Item in your ViewController. You can then set the title/style/etc of the bar button item. If nothing still shows up when you run your app, make sure that your ViewController is connected properly with a segue to the navigation controller.
Also make sure you are adding the Bar Button Item to your view controller's Navigation Item, NOT to the View Controller itself. Here is how the setup should look in your storyboard:
To add an item to a navigation bar, you need to add a Bar Button Item to the Navigation Item contained in the view controller. Go to your storyboard, find the right VC, and find the navigation item (it's in the hierarchy shown in the navigation controller 'scene'). Just drag a Bar Button Item into that hierarchy underneath the nav item, or directly onto the navbar in the visual builder display.
The navigation controller only looks at your VC's nav item when that VC is pushed onto the stack; hence modifying the VC's nav item in viewDidLoad has no effect.
(I've done this programmatically before but I don't have the code with me, so maybe I'll add that later...)