I am trying to hide the tabbar controller and display uiimageview similar to how it is done in native photo library of iphone. I have already created the library but I am having problem in displaying the images on next view by hiding tabbar. I am able to hide the tabbar but when I try to add the uiimageview it does not expend to space taken up by tab bar. I want my uiimageview to stretch till bottom of the screen.
I even want to add a button on that empty space but I am not able to do it.
My code to hide tab bar:
self.tabBarController.tabBar.hidden = YES;
Can some one please help me?
Thanks
Pankaj
Try this
self.tabBarController.tabBar.hidden = YES;
and
[imageView setFrame:CGRectMake(0,0,320,480)];
just use below two methods to hide or show tabbar controller. put this methods in delegate class so it's easy to call from any class.
- (void) hideTabBar:(UITabBarController *) tabbarcontroller {
int height = 480;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
for(UIView *view in tabbarcontroller.view.subviews) {
if([view isKindOfClass:[UITabBar class]]) {
[view setFrame:CGRectMake(view.frame.origin.x, height, view.frame.size.width, view.frame.size.height)];
}
else {
[view setFrame:CGRectMake(view.frame.origin.x,view.frame.origin.y, 320, 436)];
}
}
[UIView commitAnimations];
}
- (void) showTabBar:(UITabBarController *) tabbarcontroller {
int height = 480;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
for(UIView *view in tabbarcontroller.view.subviews) {
if([view isKindOfClass:[UITabBar class]]) {
[view setFrame:CGRectMake(view.frame.origin.x, height, view.frame.size.width, view.frame.size.height)];
}
else {
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, height)];
}
}
[UIView commitAnimations];
}
You need to set the frame of the bottom subview of the tabBarController's view property, like so:
self.tabBarController.tabBar.hidden = YES;
UIView* subview = (UIView*)[self.tabBarController.view.subviews objectAtIndex:0];
imageView.frame = subview.frame = self.window.bounds;
This is something I've used in some form in a couple of in-production products. Whether or not you actually want to utilize self.window.bounds depends on if your current class has a window property pointing to the mainWindow instance of UIWindow, whether you are supporting multiple orientations (bounds of window stays the same regardless of the current UIInterfaceOrientation, view controllers rotate, windows do not) and if you need to account for the status bar. If accounting for the status bar (UIStatusBar), offset the y & height by 20. Casting subview to UIView allows you to use dot syntax in this case (the static analyzer can't tell which objects are in an array).
I have been struggled on that for hours. Finally I found a solution. Just follow the following steps:
Tick the box Hide Bottom Bar on Push in your child view controller (the one you want to hide the tab bar) from Storyboard.
Add the following code in the viewWillAppear method in your root view controller: self.tabBarController?.tabBar.hidden = false.
Add the following code in the viewWillAppear method in your pushed view controller: self.tabBarController?.tabBar.hidden = true.
That's all. It just works!
Related
How does one hide the UITabBar programmatically? It's been asked and answered multiple times on SO, but the answers seem to come in roughly two varieties:
1) Using a navigation controller, one can hide the next vc's tab bar before the push using hidesBottomBarWhenPushed property. Typical answer here.
2) Walk through the tabbar controller's view hierarchy and modify the tab bar's frame and/or visibility. Typical answer here.
But both sorts of answers fall short, imo. 1) What if we need to hide the tab bar on the view we are on, say when rotating to landscape. 2) A half page of code waking through an Apple library's private view hierarchy is a. cumbersome, b. prone to unforseen breaking, c. possibly a blocker for app approval.
So what's an app to do? Is the answer that it's not allowed? Is there an apple document ref supporting that? It would be a sad answer. Imo, the rotation case is a legitimate reason for hiding the tab bar.
Thanks in advance for your help.
Sorry for the delayed response but I've pulled my code and you can see how I rotate my device to show a 'Map View' in full screen in landscape only.
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if(toInterfaceOrientation == UIInterfaceOrientationLandscapeRight || toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
[self hideTabBar:self.tabBarController];
[self.view bringSubviewToFront:self.eventsMapView];
self.eventsMapView.bounds = self.view.bounds;
self.eventsMapView.frame = CGRectMake(0, -208, self.view.frame.size.width, 300);
} else if(toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown || toInterfaceOrientation == UIInterfaceOrientationPortrait) {
[self showTabBar:self.tabBarController];
[self.view sendSubviewToBack:self.eventsMapView];
}
}
And since we call methods within that to actually hide and show the tab bar, we need to define those methods in our .m file as well:
#pragma mark - Tab Bar Methods -
-(void)hideTabBar:(UITabBarController *)tabbarcontroller {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
for(UIView *view in tabbarcontroller.view.subviews) {
if([view isKindOfClass:[UITabBar class]]) {
[view setFrame:CGRectMake(view.frame.origin.x, 480, view.frame.size.width, view.frame.size.height)];
} else {
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 480)];
}
}
[UIView commitAnimations];
}
-(void)showTabBar:(UITabBarController *)tabbarcontroller {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
for(UIView *view in tabbarcontroller.view.subviews) {
if([view isKindOfClass:[UITabBar class]]) {
[view setFrame:CGRectMake(view.frame.origin.x, 431, view.frame.size.width, view.frame.size.height)];
} else {
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 431)];
}
}
[UIView commitAnimations];
}
If you're already within a Tab Bar Controller then you need to make sure every child (or individual tab ViewController) returns TRUE for orientation like below.
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return TRUE;
}
Hope this helps - if you have any questions leave a comment and I'll update my answer to show it off better.
You can find some useful code here. You can call hideTabbar from your shouldrotate: method
2021 answer. Xcode 12.
Create a new layout for when in Landscape mode. in the below picture, I created wAny hCompact (hC) attribute and then set it as hidden.
I have several view controllers for various parts of a game I am working on, let's call them screens 1,2,3,4.
I would like to be able to start the game up in screen 1, then show 2, 3, 4 and then go back to screen 1 and start all over again (sometimes I want to leave out #3, etc). I have managed to get this functionality with the UITabBarController but I couldn't figure out how to hide the tab control itself. If I hid the actual control it would just display a white bar in its place. If I tried to resize the view it worked on the first screen, then the others appeared to be twice the screen size (set in viewWillAppear):
[[self view] setFrame:[[UIScreen mainScreen] bounds]];
Has anybody managed to get this sort of thing working? Would I be able to use a navigation controller to do this?
I suggest you to use UINavigationController for this because for your purpose this can be done with UINavigationController instead of UITabBarController.
But if you want to continue with UITabBarController then you can hide your UITabBarController by calling this method in your app delegate:
- (void) hideTabBar:(UITabBarController *) tabbarcontroller {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
for(UIView *view in tabbarcontroller.view.subviews)
{
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, 480, view.frame.size.width, view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 480)];
}
}
[UIView commitAnimations];
}
developers!
Im currently working on an app that uses the Tab Bar Application template. What I wanna do
is to simulate a startpage for my app that corresponds to the first tab.
So when the app start the first tab is selected and the UITabBar should not be visible.
In this "startview" there is multiple buttons that acts like the rest of the tabs, so for instance i press button #2 and the second tab view is pushed and the UITabBar is again visible.
My problem is that i have a way to hide the bar but the subview is not resizing to fullscreen.
By using:
[self.tabBarController.tabBar setHidden:YES];
I've also tried to use:
self.hidesBottomBarWhenPushed = YES;
But it seems to have no effect and I'm not sure where to add the code since I'm using
the template.
Anyone knows how to implement this by using the Tab Bar Application template?
I'm guessing it should be at the:
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController: (UIViewController *)viewController
But I've tried that and that method is never being called...
Many thanks,
Robert
THis code may help you to Hide tabbarcontroller and resize the viewcontroller.
- (void) hideTabBar:(UITabBarController *) tabbarcontroller {
int height = 480;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
for(UIView *view in tabbarcontroller.view.subviews) {
if([view isKindOfClass:[UITabBar class]]) {
[view setFrame:CGRectMake(view.frame.origin.x, height, view.frame.size.width, view.frame.size.height)];
}
else {
[view setFrame:CGRectMake(view.frame.origin.x,view.frame.origin.y, 320, 436)];
}
}
[UIView commitAnimations];
}
This second method may help you to set tababr again in view
- (void) showTabBar:(UITabBarController *) tabbarcontroller {
int height = 480;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
for(UIView *view in tabbarcontroller.view.subviews) {
if([view isKindOfClass:[UITabBar class]]) {
[view setFrame:CGRectMake(view.frame.origin.x, height, view.frame.size.width, view.frame.size.height)];
}
else {
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, height)];
}
}
[UIView commitAnimations];
}
please understand code before implementing it in your code...
I got the code from this question: How to hide UITabBarController programmatically? which is brilliant, however the view doesn't expand to fit the space left by the tab bar now.
I have set the appropriate UIViewAutoresizingMasks to the view, but I'm assuming that just because its hidden doesn't mean its not still taking up the space?
Anyway, if I do [self.navigationController setNavigationBarHidden:YES animated:YES]; then the navigation bar moves up and off the screen expanding the view with it.
How can I replicate this behavior for the Tab Bar?
Turns out its not quite possible. Best way is to present a modal view (navigation) controller instead of pushing a view controller.
This worked great for me! (combines solutions from other posts mentioned -580 is randomly large number)
for(UIView *view in self.tabBarController.view.subviews)
{
if([view isKindOfClass:[UITabBar class]])
{
[view setFrame:CGRectMake(view.frame.origin.x, 580, view.frame.size.width,
view.frame.size.height)];
}
else
{
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y,
view.frame.size.width, view.frame.size.height +40)];
}
}
-(void)hideTabBar
{ UITabBarController * tabbarcontroller= appDelegate.tabBarVC;
if (tabbarcontroller.tabBar.isHidden)
{
return;
}
tabbarcontroller.tabBar.hidden=YES;
CGRect frm=tabbarcontroller.view.frame;
frm.size.height += tabbarcontroller.tabBar.frame.size.height;
tabbarcontroller.view.frame=frm;
}
-(void)showTabBar
{ UITabBarController * tabbarcontroller=appDelegate.tabBarVC;
if (!tabbarcontroller.tabBar.isHidden)
{
return;
}
CGRect frm=tabbarcontroller.view.frame;
frm.size.height -= tabbarcontroller.tabBar.frame.size.height;
tabbarcontroller.view.frame=frm;
tabbarcontroller.tabBar.hidden=NO;
}
here appDelegate is = (AppDelegate *) [[UIApplication sharedApplication] delegate]
tabBarVc is UITabBarController *tabBarVC defined as property in app delegate
in NSContraints era, do NOT try to modify frame by code, bad things may happen.
Use:
pushedViewController.hidesBottomBarWhenPushed = YES;
typically set hidesBottomBarWhenPushed to yes in prepareforSegue, ANYWAY before iOS actually pushes the new controller.
The easiest way is probably to set a new frame for the view:
CGRect viewFrame = view.frame;
viewFrame.size.height += 40; // Change this to the height of the tab bar
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
view.frame = viewFrame;
[UIView commitAnimations];
I want to fade the whole screen (including navigation bar) to black when a user presses a button on a uinavigationcontroler, before showing a new view. (i don't want to push this new view, for various reasons).
How would I achieve this?
EDIT
Thanks to Mac and Eiko, I have figured it out. Here's the code I used. Not sure if it is optimal, but it does the trick.
// this is called from a programmatically constructed button.
// change (void) to (IBAction) if linking from IB.
- (void)fadeAndShow:(id)sender
{
// blackView is a #property which has been #synthesize-d
// do I really need to alloc and init this?
blackView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
blackView.alpha = 0.0;
[blackView setBackgroundColor:[UIColor blackColor]];
[self.navigationController.navigationBar.superview addSubview:blackView];
[UIView beginAnimations:#"fadeAway" context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.75];
[UIView setAnimationDidStopSelector:#selector(showNewScreen:finished:context:)];
blackView.alpha = 1.0;
[UIView commitAnimations];
}
-(void)showNewScreen:(NSString *)animationID finished:(BOOL)finished context:(void *)context
{
// I guess you could fade in somewhere in the new view controller.
// don't know how to fade back in this view tho... viewDidAppear?
NewViewController *controller = [[NewViewController alloc] initWithNibName:#"NewView" bundle:nil];
[self.navigationController setNavigationBarHidden:YES];
controller.hidesBottomBarWhenPushed = YES;
[[self navigationController] pushViewController:controller animated:NO];
[blackView removeFromSuperview];
[controller release];
}
Off the top of my head (I haven't actually tested the following at all):
-(IBAction) buttonClicked:(id) sender
{
[UIView beginAnimations:#"myAnimation" context:nil];
[UIView setAnimationDuration:ANIMATION_DURATION];
blackView.alpha = 1.0;
[UIView commitAnimations];
}
Create a UIView in the navigationbar's superview (which I'm assuming is window-sized) that is the same size as the window.
Set that view's backgroundColor to [UIColor blackColor], and its alpha to 0.0.
In your button handler do something like the above (assuming your new UIView is blackView and ANIMATION_DURATION is your desired animation time in seconds).
Then, add your new view on top.
EDIT: too quick for me Eiko! Also, code at the top since the ordered list seems to screw around with the code formatting - sorry the answer reads a little odd.
You can add a black coloured UIView in screen size on top of your current view, and animate its alpha from 0 to 1. When the animation is done, add your new view. You can remove the black one then. Animate from 1 to 0 for the opposite effect - going from black to the content).