I have a TabBarController with four view controllers . In my first view controller i have the following two methods:
-(void)loadclistview
{
[self.tabBarController setSelectedIndex:2];
}
-(void)loadglistview
{
[self.tabBarController setSelectedIndex:1];
}
I use them to change the view form one tab to the other. But changing tabs this way doesn't preserve my banner view, it does not load the banner into the new view controllers (tabs). If i change tabs using the tab bar , all the views load banners correctly.
Pls help me here - i don't know why this is happening , and what should i do to switch tabs through selectors so that the banner will load in the new views.
EDIT:
I solved it by adding the current bannerview as a subview to the selected viewcontroller from the tab bar ; like this:
[self.tabBarController.selectedViewController.view addSubview:_bannerView];
I saw this also works to adding the bannerview to subsequent view to a navigationcontroller - like showing the banner in child views of the main view which constitues a tab;
[self.navigationController.view addSubview:_bannerView];
Adding the subview this way is fine, but you also have to handle the show/hide of it when there is or isn't an iAd, and the resize of the content view to make room for displaying the subview. The TabbedBanner project in the Apple iAdSuite sample has a nice encapsulation of this functionality.
Related
Upon clicking the button on the first screen the user is presented with view controllers contained within a tab bar controller. The view controllers have two tableviews in them, the first a top static table and a second table just below. The view controllers in the tab bar controller that are not within the "more" display correctly. If I go to "more" and select a view controller the view is displayed with the top cell pushed down.
If I go to the "more" screen, click edit, and move the order of view controllers in any way, view controller displayed through "more" display correctly. Upon leaving the "more" section the top table cell (top table) is not displayed.
It seems reasonable to me that there is an issue in the UI or storyboard, however nothing jumps out at me as the issue. I've tried both manually setting constraints and also using suggested constraints.
This sample project is available at https://github.com/propstm/NavigationStructureTest
I simply updated the constraints in the Two Table VC , then the issue was not there.
Disable Size classes,and delete the constraint(top tableView) of "vertically space to top layout guide",add pin top space to super view can solve the problem.
Maybe it's a bug of Xcode,see this.
I think it has something to do with the "more" controller provided by the TabBarController having its own navigation controller, and your storyboard set up to extend edges beyond top bars.
Although you are trying to hide the navigation bar, I think its done in the wrong place and should only be required when the item is being presented in the "more" controller. The way its currently implemented confuses the top layout guide, which seems to be left assuming there are two top bars even though one of them is hidden.
I was able to fix your demo project in two ways. By either:
1) Update the storyboard and turn off "extend edges" on the tab bar (and set the tab bar and top bars to be opaque):
OR
2) Simplify the viewWillAppear/Disappear and viewDidAppear/Disappear methods and hide the navigation bar when within the tab bar more controller:
- (void)viewDidAppear:(BOOL)animated{
//self.navigationItem.backBarButtonItem.title = #"HOME";
self.tabBarController.title = #"Entity List";
//Pretty activity indicator
[self.topTableView reloadData];
}
- (void)viewWillAppear:(BOOL)animated {
if (self.navigationController == self.tabBarController.moreNavigationController) {
[self.tabBarController.navigationController setNavigationBarHidden:YES];
} else {
[self.navigationController setNavigationBarHidden:NO];
}
}
- (void)viewWillDisappear:(BOOL)animated {
[self.navigationController.navigationBar setHidden:NO];
}
- (void)viewDidDisappear:(BOOL)animated {
}
This ensures the top navigation appears correctly without messing up the layout guide.
I a writing an app (iOS8) that ultimately needs to load a UITabBarController via a segue from a UITableView. For the most part this setup can be done via Storyboards and works as expected, however I would also like to add a UIButtonBarItem to the destination view which is where the problems start.
A setup that works (without a UITabBarController) can be configured as follows
The button uses a "Show" segue to display the final view controller
The second UIBarButtonItems are added by copying over the Navigation Item from the first view controller (How to add buttons to navigation controller visible after segueing?)
If I run this in the Simulator, everything works as expected and I see both the back button and the desired "Add" UIBarButtonItem:
If I then embed the final view controller in a UITabBarController, the UIBarButtonItem I added disappears and so far any changes I have made to the storyboard setup (adding a UINavigationController in between the UITabBarContoller and the last view for example) or attempts to add the UIBarButtonItem programatically don't make a difference:
Is there anyway to get the final setup working with both a UITabBarController and UIBarButtonItems?
I have the same setup in one of my apps and it works fine. Not sure why you are having issues, but I did add a few lines of code in my custom Tab Controller that may help you. I think the issue is that the nav bar from the original navigation controller is still being shown, so subclass UITabBarController and put these lines in viewWillAppear:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationItem setHidesBackButton:YES];
[self.navigationController setNavigationBarHidden:YES];
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}
In my app, the views before the tab bar controller were login/register views, so there was no reason to navigate back to them after entering the tab controller "stack," but I'm sure it won't be difficult to add a back button that accomplishes this. I believe you only need the [self.navigationController setNavigationBarHidden:YES]; line, which only hides the nav bar instead of hiding the back button or disallowing the pop gesture.
I know this is late but I just want to add swift 3 code.
The reason being that the NavigationBarA of the tabBarController is hiding your NavigationBarB that sits in between your tabBarController and the final ViewController. So you just have to set to hide the NavigationBarA
in viewWillAppear of your final ViewController you can add the following (without a need to subclass tabBarController)
self.tabBarController?.navigationController?.setNavigationBarHidden(true, animated: false)
I want to use UITabBarController but I do not need a tab bar because I'm going to switch tabs from the menu in another view controller. I want to remove it as it will be never used. I've created a subclass of UITabBarController and put this code:
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tabBar removeFromSuperview];
}
Is that safe to remove tab bar that way?
Update: Why tab bar controller?
Apple suggests to use standard container view controllers whenever it possible. I'm trying to follow that. My screens workflow is the same as for tabs, except that they are switched by left side menu, not by the tab bar.
When I use a UIViewController and change it's child view controller I've got a lot of problems when autolayouts are not working properly.
The other reason is that I want to use story board, rather then create segues from the code so I can see my app workflow easily.
When you are saying, you don't want to use it, then why to remove it. You can go with a
tabbarcontroller with hidden tabbar. I am switching tabs from the bottom custom bar.
I am doing an app, which has a tababr controller with three items. Instead of using system tab, I am creating a custom view at the footer like tab & have actually set the hidden property of tabbarController's tabbar to YES.
myTabBarController.tabBar.hidden = YES;
Try this code
[app.navigationController.view removeFromSuperview];
[app.tabbarcontroller.view removeFromSuperview];
[app.window addSubview:app.navigationController.view];
[app.navigationController popToRootViewControllerAnimated:YES];
Im trying to create a loading view controller before it loads my tableView. This works fine.
However when the tableView is displayed I get a back button. When clicked it takes me back to the loading view. Im guessing this is because its embedded inside of the navigation controller. Please advise.
if you want to hide the back button just add
self.navigationController.navigationBarHidden=YES;
in the third View controller's viewDidLoad
else add
self.navigationItem.hidesBackButton=YES;
You have different options to choose from, depending on your needs:
The loading view can push the navigation controller.
You could avoid using a full view controller to do your loading, and instead just set a view above the rest of your "offers view controller".
Or, refers to Raon answers if you just want the button to disappear
The navigation controller will keep all the controllers that you pushed in a navigation stack.
So if you push ladingviewcontroller using navigation controller and then pushing tableview controller the navigation stack will contain both the controllers and thats why on pressing back button, you are navigated to loadingViewController.
What I suggest is to remove loadingviewcontroller and show loading view in your tableviewcontroller before loading the tableview. Like, in viewWillAppear of tableviewcontroller, just add a UIView with loading indicator and add it as a subview of tableviewcontroller and remove it after you are ready to show your tableview.
Well, if you just want to hide the back nav bar button, you can do this
[self.navigationController.navigationItem setHidesBackButton:YES animated:YES];
But the better way to show the loading controller's view would be this,
[self.view addSubview:loadingController.view];
[loadingController willMoveToParentViewController:self];
[self addChildViewController:loadingController];
[loadingController didMoveToParentViewController:self];
just hide it or remove it from superView when loading view is not required. You can even animate it while hiding so that it gives a nicer effect.
Here we have a architecture issue, the best way is the following:
Make the 2 and 3 view a single one. I mean you must add the ActivityIndicator at the center of the view that contains the table view.
Make the table view hidden and startAnimating the UIActivityIndicatorView.
Do all your loading stuff.
When you finish loading, stopAnimating your UIActivityIndicatorView and make the table view visible again.
And that's it ;)
Do not push the offers load view controller via navigationController, just subview its view on the offersviewcontroller (the third one) like this in the viewDidLoad method:
OffersLoadViewController *offerLoadView = [[OffersLoadViewController alloc] initWithNibName:#"OffersLoadViewControllerv" bundle:nil];
[self.view addSubview: offerLoadView.view];
After dealing with loading just remove it:
[offerLoadView.view removeFromSuperview];
How to add iAd below the Tab bar, I have added tab bar in rootviewcontroller
self.window.rootViewController = tabBarController;
For a any single view controller adding iAd in viewController by
[self.contentView addSubview:viewController1.view];
[self.view addSubview:contentView];
[self.view addSubview:adBannerView];
is working , but the code for tab bar controller
[self.contentView addSubview:tabBarcontroller.view];
[self.view addSubview:contentView];
the tab bar controller not loaded,
How to add this, thanks in adv
The best is that you follow the pattern described in iAD suite (a sample code on Apple site). the best advantage that you get is that you don't lost the banner while changing view controller. The idea is that you have an instance of a BannaerManager that shares its iAD banner with a visible BannerViewController that is a container for you VC.
Solved by,created a seperate view controller similar to mentioned in Example iAdsuit
Try to pass your tab bar controller to banner view controller by
self.window.rootViewController = [[BannerViewController alloc]initWithContentViewController:tabBarController];
If you want the banner to persist between the tabs and not disappear when rapidly switching tabs, you've got to do the iAd Suite approach: http://developer.apple.com/library/ios/#samplecode/iAdSuite/Introduction/Intro.html
Moreover, you have to have a relationship segue from your tab bar controller to a View Controller that has container view embedded into it. Do that in your storyboard. Also, you need to set Custom Class to BannerViewController for each tab, and embed your content into the embedded view. Take a look at this post for details on how to do it it the Storyboard: https://stackoverflow.com/a/16205420/5007500
If you are not using Storyboard - you need to set BannerViewController as parent view controller for each of your tabs.