Create UILabel on any view controller from a method - iphone

I have a method that gets called if a video upload to Facebook has failed. If that method is called then I would like for a UILabel to briefly appear in any view controller that a user happens to be on at the time the upload fails.
Is this possible?
I asked a similar question earlier about a UIAlertView, but I realized that there are certain circumstances under which an alert could negatively impact user experience.

You can do this is many ways -
1) you can add UILabel to your applications main Window.
2) if you are using a UINavigationController then you get the instance of current viewcontroller and then can add UILabel to its view.
3) if you are using a UITabBarController in this case you can also get the instance of current viewcontroller by accessing tabBarController's selected viewcontroller.

this code Im posting below is from HackBook sample app from facebook. they done similar to what you want.
- (void)showMessage:(NSString *)message {
CGRect labelFrame = messageView.frame;
labelFrame.origin.y = [UIScreen mainScreen].bounds.size.height - self.navigationController.navigationBar.frame.size.height - 20;
messageView.frame = labelFrame;
messageLabel.text = message;
messageView.hidden = NO;
// Use animation to show the message from the bottom then
// hide it.
[UIView animateWithDuration:0.5
delay:1.0
options: UIViewAnimationCurveEaseOut
animations:^{
CGRect labelFrame = messageView.frame;
labelFrame.origin.y -= labelFrame.size.height;
messageView.frame = labelFrame;
}
completion:^(BOOL finished){
if (finished) {
[UIView animateWithDuration:0.5
delay:3.0
options: UIViewAnimationCurveEaseOut
animations:^{
CGRect labelFrame = messageView.frame;
labelFrame.origin.y += messageView.frame.size.height;
// UIView *messageView; declared in header
messageView.frame = labelFrame;
}
completion:^(BOOL finished){
if (finished) {
messageView.hidden = YES;
messageLabel.text = #"";
}
}];
}
}];
}

Related

Block not being called and not animating in IOS 7

I am using ShakingAlertView in my app.
https://github.com/lukestringer90/ShakingAlertView
It works perfectly in IOS 6. But after i updating to IOS 7 it didnt animate and the block function for incorrect handing not being called.
Given below is the code for the initialization of shaking alert view.
currentPass = [[ShakingAlertView alloc]initWithAlertTitle:#"Enter Current Password" checkForPassword:self.pass
usingHashingTechnique:HashTechniqueMD5
onCorrectPassword:^{
isCurrentPassConfirmed = YES;
[self._accountSource willScrollToTop];
self.password.text = #"";
[self.password becomeFirstResponder];
} onDismissalWithoutPassword:^{
//NSLog(#"hi");
[self showFailedPasswordAlert];
}];
currentPass.alertViewStyle = UIAlertViewStyleSecureTextInput;
[currentPass show];
Below is the method to animate for shake effect.This is invoked correctly but there is no effect.
- (void)animateIncorrectPassword {
// Clear the password field
_passwordField.text = nil;
// Animate the alert to show that the entered string was wrong
// "Shakes" similar to OS X login screen
CGAffineTransform moveRight = CGAffineTransformTranslate(CGAffineTransformIdentity, 20, 0);
CGAffineTransform moveLeft = CGAffineTransformTranslate(CGAffineTransformIdentity, -20, 0);
CGAffineTransform resetTransform = CGAffineTransformTranslate(CGAffineTransformIdentity, 0, 0);
[UIView animateWithDuration:0.1 animations:^{
// Translate left
self.transform = moveLeft;
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.1 animations:^{
// Translate right
self.transform = moveRight;
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.1 animations:^{
// Translate left
self.transform = moveLeft;
} completion:^(BOOL finished) {
[UIView animateWithDuration:0.1 animations:^{
// Translate to origin
self.transform = resetTransform;
}];
}];
}];
}];
}
Please help me.
iOS7 does not allow you to customize the UIAlertview.
Better create the custom view subclass of UIView which is draw the
view programmatically using - (void)drawRect:(CGRect)rect method.
And create one more container class(inherited from NSObject) which
is used to create and bind your title/password and OK buttons
with your custom delegate property into your customized alert
view.So that we can implement our custom delegate method as like
clickedButtonAtIndex method.
Upto my knowledge there is no changes in block/animation in iOS7.
Or refer this link https://github.com/wimagguc/ios-custom-alertview
The layout of UIAlertView changed drastically is iOS 7, making it almost impossible to customise and alter. You're going to have to come up with a new solution.

How do I pass touch events through to parentViewController?

I have a UIViewContoller with a few container(child) UIiewsController. The main UIViewController (mvc) contains:
1.) A UICollectionView that occupies the entire view of mvc (it is above mvc.view but below all other controls).
2.) A UIViewController that displays search options (s1vc)
3.) another similar to #2 (s2vc)
4.) another similar to #2 (s3vc)
I have added gesture recognizers to mvc so that a user can hide/show each of the child view controllers by swiping them off of the screen.
The problem is that when a user swipes any of the svcs off of the screen, they cannot scroll the mvc's collectionView.
Here is how I am hiding/showing the svcs:
-(void)swipeLeftGestureHandler:(UIGestureRecognizer*)gestureRecognizer{
SMLOG(#"Swiped Left");
if([SMUser activeUser] == nil) return;
if([self gestureHorizontalScreenSide:gestureRecognizer] == kHorizontalScreenSideLeft){
[self hideFacets];
}
else{
[self showAccordion];
}
}
-(void)swipeRightGestureHandler:(UIGestureRecognizer*)gestureRecognizer{
SMLOG(#"Swiped Right");
if([SMUser activeUser] == nil) return;
if([self gestureHorizontalScreenSide:gestureRecognizer] == kHorizontalScreenSideLeft){
[self showFacets];
}
else{
[self hideAccordion];
}
}
-(void)hideFacets{
if(self.facetVisible == NO) return;
[UIView animateWithDuration:0.25
animations:^{
CGRect newFrame = self.facetViewController.view.frame;
newFrame.origin = CGPointMake(newFrame.origin.x - newFrame.size.width, newFrame.origin.y);
self.facetViewController.view.frame = newFrame;
self.facetVisible = NO;
}
completion:^(BOOL finished){
self.facetViewController.view.hidden = YES;
self.facetViewController.view.userInteractionEnabled = NO;
}];
}
-(void)showFacets{
if([SMUser activeUser] == nil) return;
if(self.facetVisible == YES) return;
self.facetViewController.view.userInteractionEnabled = YES;
[UIView animateWithDuration:0.25
animations:^{
self.facetViewController.view.hidden = NO;
CGRect newFrame = self.facetViewController.view.frame;
newFrame.origin = CGPointMake(newFrame.origin.x + newFrame.size.width, newFrame.origin.y);
self.facetViewController.view.frame = newFrame;
self.facetVisible = YES;
}
completion:^(BOOL finished){
}];
}
As you can see I'm toggling the svc.view.hidden property and then I also tried toggling th svc.userInteractionEnabled.property but no luck. Still cannot swipe the collection view by swiping where the facets view controller was/is.
Any ideas?
The solution here is to add another outlet (using IB) for the container view in the parentViewController (I called it facetContainerView in this code) and then set it's userInteractionEnabled property.
-(void)hideFacets{
if(self.facetVisible == NO) return;
self.facetVisible = NO;
[UIView animateWithDuration:0.25
animations:^{
CGRect newFrame = self.facetViewController.view.frame;
newFrame.origin = CGPointMake(newFrame.origin.x - newFrame.size.width, newFrame.origin.y);
self.facetViewController.view.frame = newFrame;
}
completion:^(BOOL finished){
self.facetViewController.view.hidden = YES;
self.facetContainerView.userInteractionEnabled = NO;
}];
}
-(void)showFacets{
if(self.facetVisible == YES) return;
self.facetVisible = YES;
self.facetContainerView.userInteractionEnabled = YES;
[UIView animateWithDuration:0.25
animations:^{
self.facetViewController.view.hidden = NO;
CGRect newFrame = self.facetViewController.view.frame;
newFrame.origin = CGPointMake(newFrame.origin.x + newFrame.size.width, newFrame.origin.y);
self.facetViewController.view.frame = newFrame;
}
completion:^(BOOL finished){
}];
}
I was curious as to how this new view outlet was different from self.facetViewController.view, so I inserted this code to compare addresses (they are different indeed). I'm not sure about the heirarchy, but it seems that there is an extra view layer that I was not aware of.
NSLog(#"self.facetViewController.view: %p", self.facetViewController.view);
NSLog(#"self.facetContainerView: %p", self.facetContainerView);
Hopefully this will help someone at some point.

Cannot change UIView frame size

I have a custom uiview that i am trying to update the frame size. I do it like this in a method once it is clicked. The method is called, and the frame value changes, however on the screen nothing happens!
if (!touched) {
GameBox *box = (GameBox *)[self.view viewWithTag:40];
[box setFrame:CGRectMake(20, 20, 100, 73)];
NSLog(#"%f", box.frame.origin.x);
markButton.enabled = NO;
guessButton.enabled = NO;
[self.view reloadInputViews];
NSLog(#"The action bar should now be hidden");
}
else if (touched) {
guessButton.enabled = YES;
markButton.enabled = YES;
[self.view reloadInputViews];
NSLog(#"The action bar should now be visible");
}
I guess you have hooked self.view to UIView in Interface Builder.
In order to change UIView frame, in Interface Builder go to File Inspector, and uncheck Use Autolayout, then in the code change the frame.
Hope this helps.
You need to set adjust the frame in the viewDidAppear (not viewDidLoad).
- (void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
CGRect frame = self.tableView.frame;
frame.origin.y += 100.0;
frame.size.height -= 100.0;
self.tableView.frame = frame;
}
Apparently this has something to do with table views within navigation controllers.
It is because of Auto Layout, however you could do it after Auto Layout done its work or change constraints of it. If you want to do it after auto layout add following.
- (void)viewDidAppear:(BOOL)animated {
dispatch_async(dispatch_get_main_queue(), ^{
box.frame = CGRectMake(20, 20, 100, 73)];
});
[self.view reloadInputViews] is generally used for FirstResponders. I Don't have much of an idea about your customview, but I think for just settings the frame you can use:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:1.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
viewFrame.frame=frame;//Frame Defined by you
[UIView commitAnimations];
can give better solution if i get a look at your custom view.

Why does the keyboard not show in my UITextView?

I have a container class which is a view controller.
It holds the UITextView for notes and has another view controller as a subview, called it PDFViewController. That one has an array of view controllers, called them PageViewController's, in it and a UIScrollView so i can swipe through the different view controllers from the array.
Each of the PageViewController's has also an UIScrollView, so i can zoom the different pages.
But when I show my UITextView i cannot edit or write anything.
It shows a blinking cursor, but no keyboard and can't write text.
When i highlight a word from the default text, it shows me some dictionary options but the words won't be replaced.
I just don't know where the problem might be.
container.m (View Controller)
- (void) initNotes {
notesVisible = FALSE;
notes = [[UITextView alloc]initWithFrame:CGRectMake(10, 10, note_width, note_height)];
notes.backgroundColor = [UIColor yellowColor];
notes.font = [UIFont fontWithName:#"Arial" size:24];
notes.text = #"Hier ist Platz für Ihre Notizen";
container = [[UIView alloc] initWithFrame:CGRectMake(start_x, start_y, container_width, container_height)];
container.backgroundColor = [UIColor yellowColor];
[container.layer setShadowColor:[[UIColor blackColor] CGColor]];
[container.layer setShadowOffset:CGSizeMake(2.0, 3.0)];
[container.layer setShadowOpacity:0.6];
[container.layer setShadowRadius:5];
container.layer.shouldRasterize = YES;
[container addSubview:notes];
[self.view addSubview:container];
}
- (void) showTextView {
[UIView beginAnimations:#"MoveAndStrech" context:nil];
[UIView setAnimationDuration:0.4];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
container.frame = CGRectMake(start_x, self.view.center.y-container_height, container_width, container_height);
[UIView commitAnimations];
notesVisible = !notesVisible;
}
- (void) hideTextView {
[UIView beginAnimations:#"MoveAndStrech" context:nil];
[UIView setAnimationDuration:0.4];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
container.frame = CGRectMake(start_x, start_y, container_width, container_height);
// [notes resignFirstResponder];
[UIView commitAnimations];
notesVisible = !notesVisible;
}
#implementation PDFViewController
- (void)awakeFromNib
{
painting = false;
dataInstance = [PDFDataInstance sharedInstance];
chapter = [dataInstance chapter];
[self getNumberOfPages];
kNumberOfPages = dataInstance.pages;
// Register observer to be called when a cell from BookmarkPDFController is pressed
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(didSelectBookmark:)
name:#"bookmarkPressedinPDFView" object:nil];
// Register observer to be called when a cell from BookmarkPDFController is pressed
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(togglePainting:)
name:#"togglePainting" object:nil];
// view controllers are created lazily
// in the meantime, load the array with placeholders which will be replaced on demand
NSMutableArray *controllers = [[NSMutableArray alloc] init];
for (unsigned i = 0; i < kNumberOfPages; i++)
{
[controllers addObject:[NSNull null]];
}
self.viewControllers = controllers;
[controllers release];
// a page is the width of the scroll view
scrollView.pagingEnabled = YES;
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * kNumberOfPages, scrollView.frame.size.height);
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.showsVerticalScrollIndicator = NO;
scrollView.delegate = self;
scrollView.directionalLockEnabled = YES;
currentPage = [[chapter currentPage] integerValue];
// pages are created on demand
// load the visible page
// load the page on either side to avoid flashes when the user starts scrolling
//
// Load pages based on currentPage cause of when coming from bookmarks
[self loadScrollViewWithPage:currentPage];
[self loadScrollViewWithPage:currentPage+1];
// update the scroll view to the appropriate page
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * currentPage;
frame.origin.y = 0;
[scrollView scrollRectToVisible:frame animated:YES];
}
- (void)loadScrollViewWithPage:(int)page
{
if (page < 0)
return;
if (page >= kNumberOfPages)
return;
// replace the placeholder if necessary
PageViewController *controller = [viewControllers objectAtIndex:page];
if ((NSNull *)controller == [NSNull null])
{
//page+1 cause CGPDF indexing starts with 1
controller = [[PageViewController alloc] initWithPageNumberAndUrl:page+1: [chapter urlOnFilesystem]];
[viewControllers replaceObjectAtIndex:page withObject:controller];
[controller release];
}
// add the controller's view to the scroll view
if (controller.view.superview == nil)
{
CGRect frame = scrollView.frame;
frame.origin.x = frame.size.width * page;
frame.origin.y = 0;
controller.view.frame = frame;
[scrollView addSubview:controller.view];
}
}
TextView delegates
- (void)textViewDidBeginEditing:(UITextView *)textView {
NSLog(#"begin editing");
}
- (BOOL)textView:(UITextView *)aTextView shouldChangeTextInRange:(NSRange)aRange replacementText:(NSString*)aText
{
NSLog(#"something changed");
return YES;
}
Just want to add another possibility here. In the iOS simulator, make sure the "Hardware/Keyboard/Connect Hardware Keyboard" is not checked. It took me a couple of hours to figure out this. I guess I toggled that option by accidently pressing the shortcut. Not good experience :(
As pictured, Connect Hardware Keyboard should be UN-checked.
Is the UITextView receiving touches? Implement the UITextViewDelegate methods and see if they get called (esp textViewDidBeginEditing: and textView: shouldChangeTextInRange: replacementText:). This way you'll know for sure whether the text view is indeed handling the touches or not.
If it does, then I don't see anything wrong with your code (except you might have accidentally added a view overlapping the textview)
No one asked , but have you set :
notes.editable = YES ;
?
Make sure that in the delegate of your textview. Following method is returning YES.
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
return YES;
}
After you have set the notes delegates, do the following.
- (void)textViewDidBeginEditing:(UITextView *)textView {
if ([textView isEqual:notes]) {
NSLog(#"notes begin editing");
}
}
- (BOOL)textView:(UITextView *)aTextView shouldChangeTextInRange:(NSRange)aRange replacementText:(NSString*)aText {
if ([aTextView isEqual:notes]) {
NSLog(#"something changed in notes");
}
return YES;
}
This should confirm delegates of notes are indeed getting called.
you need to implement your container class with UITextViewDelegate
and add notes.delegate=self; just after initialize the notes object in initNotes method.
Check for 2 things:
Is notes.editable = YES; if so please change it to NO.
2.Check whether your UITextView delegates are called are not. If not Please make sure you include in your implementation file and set notes.delegate = self.
Try without container, just use the UITextView (notes) as the container itself.
Every time you used container use notes instead.
And then dont:
[container addSubview:notes];
[self.view addSubview:container];
Just:
[self.view addSubview:notes];
Tell me how it goes
I had similar behavior, the UITextView not responding to touches and the keyboard not showing.
My UITextView was layered on top of a UICollectionView which was receiving all the touches even though the UITextView was visibly on top.
I fixed it by adjusting the frame of the UICollectionView so that the UITextView has nothing behind it. After that, all the delegate methods were called like a charm.
Hope this helps.
please Refer this one. where ContantView is your view/textfield and _bubbletable is your table.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
[UIView animateWithDuration:0.2f animations:^{
CGRect frame = _ContantView.frame;
frame.origin.y -= kbSize.height;
_ContantView.frame = frame;
frame = _bubbleTable.frame;
frame.size.height -= kbSize.height;
_bubbleTable.frame = frame;
}];
}

Iphone: Is it possible to hide the TabBar? (Pre-iOS 8)

I have an application that uses a UITabBarController to switch between modes. When in a certain mode, I'd like to hide the tab bar until the steps of that mode have been completed. Note that I'm not using a navigation controller so I can't use the setHidesBottomBarWhenPushed method on the navigation controller to hide the tab bar.
Prior to iOS 8, When I attempt to hide the tarbar using:
self.tabBarController.tabBar.hidden = YES
the tab bar goes away, but it leaves a 50 pixel blank area at the bottom of the screen where the tab bar used to be. I can't seem to figure out how to fill that area. Anything in the UI that is in that area is clipped and cannot be seen.
Any ideas if this is even possible? I'd really like to stay away from the navigation controller.
Here's my code for that:
This is, of course, mucking with the goings on in the controller's view hierarchy. It could change/break. This uses defined APIs, so Apple won't care, but they won't care about breaking your code, either.
- (void)hideTabBar {
UITabBar *tabBar = self.tabBarController.tabBar;
UIView *parent = tabBar.superview; // UILayoutContainerView
UIView *content = [parent.subviews objectAtIndex:0]; // UITransitionView
UIView *window = parent.superview;
[UIView animateWithDuration:0.5
animations:^{
CGRect tabFrame = tabBar.frame;
tabFrame.origin.y = CGRectGetMaxY(window.bounds);
tabBar.frame = tabFrame;
content.frame = window.bounds;
}];
// 1
}
- (void)showTabBar {
UITabBar *tabBar = self.tabBarController.tabBar;
UIView *parent = tabBar.superview; // UILayoutContainerView
UIView *content = [parent.subviews objectAtIndex:0]; // UITransitionView
UIView *window = parent.superview;
[UIView animateWithDuration:0.5
animations:^{
CGRect tabFrame = tabBar.frame;
tabFrame.origin.y = CGRectGetMaxY(window.bounds) - CGRectGetHeight(tabBar.frame);
tabBar.frame = tabFrame;
CGRect contentFrame = content.frame;
contentFrame.size.height -= tabFrame.size.height;
}];
// 2
}
Edit:
An anonymous user has suggested the following addition for 7.0 (i have not tested this, and could not say whether it is a workaround or an ideal implementation):
// 1. To Hide the black line in IOS7 only, this extra bit is required
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7.0")) {
[self.tabBarController.tabBar setTranslucent:YES];
}
// 2. For IOS 7 only
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7.0")) {
[self.tabBarController.tabBar setTranslucent:NO];
}
Edit: Entirely untested in 8.x and likely lacking in some layouts.
Like Steve, I haven't found a clean way to do this (even though Apple Photopicker does something similar). Here is what I have done:
if (systemAction)
{
// Reveal tab bar back
CGRect bounds = [[UIScreen mainScreen] bounds];
CGRect tabBarFrame = self.tabBarController.tabBar.frame;
self.tabBarController.view.frame = CGRectMake(0,0,bounds.size.width,bounds.size.height);
self.toolBar.hidden = YES;
systemAction = NO;
}
else
{
//hide tab bar
CGRect bounds = [[UIScreen mainScreen] bounds];
CGRect tabBarFrame = self.tabBarController.tabBar.frame;
CGRect navigationBarFrame = self.navigationController.navigationBar.frame;
self.tabBarController.view.frame = CGRectMake(0,0,bounds.size.width,bounds.size.height+tabBarFrame.size.height);
self.toolBar.hidden = NO;
CGRect frame = self.toolBar.frame;
frame.origin.y = bounds.size.height - frame.size.height - navigationBarFrame.size.height;
self.toolBar.frame = frame;
systemAction = YES;
}
What it is doing is pushing the view down so I can display a toolbar (and not hiding it). Obviously this is for only the 'root view' of a tabbar + navigation controller. For any subsequent views you can set the 'hidesBottomBarWhenPushed' on the viewcontroller you are pushing.
I tried a number of the solutions above, but no joy in iOS 8. I find that setting in viewWillAppear the following works for me. Should work in iOS 7 as the extendedLayoutIncludesOpaqueBars was introduced then.
self.extendedLayoutIncludesOpaqueBars = true
self.tabBarController?.tabBar.isHidden = true
self.tabBarController?.tabBar.isOpaque = true
and if you need to turn tabBars on again when you leave to use the following in viewWillDisappear.
self.tabBarController?.tabBar.isHidden = false
self.tabBarController?.tabBar.isOpaque = false
I use this to allow a return from a transition to keep the TabBar hidden. Not used it in a button action but if like me you find nothing above now works, this could be the basis of a programmable solution.
It's a bit late in the day, but of all the answers to the question that I've trawled through this afternoon, this is the one that worked best for me.
How to hide uitabbarcontroller
// Method call
[self hideTabBar:self.tabBarController];
// Method implementations
- (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];
}
- (void)showTabBar:(UITabBarController *) tabbarcontroller
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
for(UIView *view in tabbarcontroller.view.subviews)
{
NSLog(#"%#", view);
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];
}
I use only this single line to achieve this. I use prepareForSegue method before showing the view controller having the tab bar.
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"showLogin"]){
[segue.destinationViewController setHidesBottomBarWhenPushed:YES];
}
}
I had worked on almost the same case, actually used the code from http://www.developers-life.com/hide-uitabbarcontrolleruitabbar-with-animation.html and made it better according to my needs, this might help others too.
I am using a UISplitViewController as the root view controller and its detail portion is a UITabBarController, I had to hide the tabbar in portrait mode:
// In UITabBarController's custom implementation add following method,
// this method is all that will do the trick, just call this method
// whenever tabbar needs to be hidden/shown
- (void) hidetabbar:(NSNumber*)isHidden {
UITabBarController *tabBarController=self;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
CGRect tabbarFrame=CGRectZero;
for(UIView *theView in tabBarController.view.subviews) {
//NSLog(#"%#", view);
if([theView isKindOfClass:[UITabBar class]]) {
tabbarFrame=theView.frame;
if ([isHidden boolValue]) {
tabbarFrame=CGRectMake(tabbarFrame.origin.x,
tabBarController.view.frame.size.height,
tabbarFrame.size.width,
tabbarFrame.size.height);
} else {
tabbarFrame=CGRectMake(tabbarFrame.origin.x,
tabBarController.view.frame.size.height - tabbarFrame.size.height,
tabbarFrame.size.width,
tabbarFrame.size.height);
}
theView.frame=tabbarFrame;
break;
}
}
for(UIView *theView in tabBarController.view.subviews) {
if(![theView isKindOfClass:[UITabBar class]]) {
CGRect theViewFrame=theView.frame;
if ([isHidden boolValue]) {
theViewFrame=CGRectMake(theViewFrame.origin.x,
theViewFrame.origin.y,
theViewFrame.size.width,
theViewFrame.size.height + tabbarFrame.size.height);
} else {
theViewFrame=CGRectMake(theViewFrame.origin.x,
theViewFrame.origin.y,
theViewFrame.size.width,
theViewFrame.size.height - tabbarFrame.size.height);
}
theView.frame=theViewFrame;
}
}
[UIView commitAnimations];
}
I used following code to call the hidetabbar: method
//In my UISplitViewController's custom implementation
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
#synchronized(self){
//change the self.splitDetailController to your UITabBarController's object
[self.splitDetailController
performSelector:#selector(hidetabbar:)
withObject:[NSNumber numberWithBool:UIInterfaceOrientationIsLandscape(interfaceOrientation)]
afterDelay:0.5];
}
return YES;
}
I tested this code to work in simulator only, let me know if it works on device too ;-)
Do you have the autoResizingMask set on the sub view?
view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
Something like that should do the trick and allow the view sitting atop the stack to re-size.
The obvious solution, keeping your original architecture, would have been to present that view modally:
- (void)tabBarController:(UITabBarController *)tb
didSelectViewController:(UIViewController *)vc {
if (tb.selectedIndex == MODALONE) {
UIViewController* mod =
[[UIViewController alloc] initWithNibName: #"ModalView"
bundle: nil];
[tb presentModalViewController:mod animated:NO];
[mod release];
}
}
The view now covers the entire screen (except for the status bar is there is one) including the tab bar, so it looks as if the tab bar has gone away in response to the user pressing that tab bar item.
autoresizing mask has an enumeration. Try to set all the options and check if autoresize subviews option is checked in parent view
You can create Tabbar Category and show/Hide easily. and you can access full view.
create category #import "UITabBarController+HideTabBar.h"
#implementation UITabBarController (HideTabBar)
- (void)hideTabBarAnimated:(BOOL)animated
{
CGRect statusbarFrame = [UIApplication sharedApplication].statusBarFrame;
CGRect tabBarControllerFrame = self.view.frame;
if (statusbarFrame.size.height>20)
{
tabBarControllerFrame.size.height = screenSize.size.height + self.tabBar.frame.size.height - 20.0;
}
else
{
tabBarControllerFrame.size.height = screenSize.size.height + self.tabBar.frame.size.height ;
}
if (animated) {
[UIView animateWithDuration:0.2 animations:^{
[self.view setFrame:tabBarControllerFrame];
} completion:^(BOOL finished) {
}];
}
else
[self.view setFrame:tabBarControllerFrame];
}
- (void)showTabBarAnimated:(BOOL)animated {
CGRect statusbarFrame = [UIApplication sharedApplication].statusBarFrame;
CGRect tabBarControllerFrame = self.view.frame;
if (statusbarFrame.size.height>20)
{
tabBarControllerFrame.size.height = screenSize.size.height - 20.0;
}
else
{
tabBarControllerFrame.size.height = screenSize.size.height ;
}
if (animated) {
[UIView animateWithDuration:0.2 animations:^{
[self.view setFrame:tabBarControllerFrame];
} completion:^(BOOL finished) {
}];
}
else
[self.view setFrame:tabBarControllerFrame];
}
#end
Note : use statusbarFrame is used when hotspot or call is ON so tabbar would not cut down.
Now Import category in which you class you want to use methods and just call below methods to hide or show tabbar.
[self.tabBarController hideTabBarAnimated:YES];
[self.tabBarController showTabBarAnimated:YES];
Hope this Helps.
Hope this works.
#interface UITabBarController (Additions)
-(void)setTabBarHidden:(BOOL)hidden animated:(BOOL)animated;
#end
#implementation UITabBarController (Additions)
-(void)setTabBarHidden:(BOOL)hidden animated:(BOOL)animated
{
if (animated)
{
[UIView beginAnimations:nil context:nil];
}
if (hidden)
{
self.tabBar.frame = CGRectMake(self.tabBar.frame.origin.x, self.tabBar.superview.frame.size.height, self.tabBar.bounds.size.width, self.tabBar.bounds.size.height);
}
else
{
self.tabBar.frame = CGRectMake(self.tabBar.frame.origin.x, self.tabBar.superview.frame.size.height - self.tabBar.frame.size.height + 10, self.tabBar.bounds.size.width, self.tabBar.bounds.size.height);
}
if (animated)
{
[UIView commitAnimations];
}
}
Here is my solution (my tab view controller is inside navigation controller for good measure)... So I have subclassed UITabBarController and did this... exposing -setTabBarHidden: method
- (void)setTabBarHidden:(BOOL)hidden {
_tabBarHidden = hidden;
[UIView performWithoutAnimation:^{
[self adjustViews];
}];
}
- (void)adjustViews {
if ( _tabBarHidden ) {
CGRect f = self.tabBar.frame;
// move tab bar offscreen
f.origin.y = CGRectGetMaxY(self.view.frame);
self.tabBar.frame = f;
// adjust current view frame
self.selectedViewController.view.frame = self.view.frame;
} else {
CGRect f = self.tabBar.frame;
// move tab bar on screen
f.origin.y = CGRectGetMaxY(self.view.frame) - (CGRectGetMaxY(self.tabBar.bounds) + CGRectGetMaxY(self.navigationController.navigationBar.frame));
self.tabBar.frame = f;
// adjust current view frame
f = self.view.bounds;
f.size.height -= CGRectGetMaxY(self.tabBar.bounds);
self.selectedViewController.view.frame = f;
}
}
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
[UIView performWithoutAnimation:^{
[self adjustViews];
}];
}
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
[UIView performWithoutAnimation:^{
[self adjustViews];
}];
}
put the statement in the init method of the UIViewController
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
self.hidesBottomBarWhenPushed = true
setupDependencyConfigurator()
}
See this thread:
Show/Hide TabBarController in iphone
In summary, you can see an example of this behavior in this sample code:
http://developer.apple.com/iphone/library/samplecode/TheElements/index.html
Why are you not using a navigation controller. It's a lot easier to hide the nav bar than the tab bar...
Just made the following code in Monotouch inside a subclass of UITabBarController:
public void ShowTabBar()
{
UIView.BeginAnimations("Anim");
UIView.SetAnimationDuration(0.25f);
this.View.Subviews[0].Frame = new RectangleF(0f, 0f, 320f, 431f);
this.TabBar.Frame = new RectangleF(0f, 431f, 320f, 49f);
this.TabBar.Hidden = false;
UIView.CommitAnimations();
}
public void HideTabBar()
{
UIView.BeginAnimations("Anim");
UIView.SetAnimationDuration(0.25f);
this.View.Subviews[0].Frame = new RectangleF(0f, 0f, 320f, 480f);
this.TabBar.Frame = new RectangleF(0f, 481f, 320f, 510f);
this.TabBar.Hidden = true;
UIView.CommitAnimations();
}