Tab Bar controller is not accessible - iphone

I have created a tab based application for iphone. when the 1st tab presses a first view will present. this view contains a button, on pressing it another view loads.
Code is:
-(IBAction)buttonPressed: (id) sender
{
Cities *cv=[[Cities alloc] initWithNibName:#"Cities" bundle:nil];
cv.modalTransitionStyle=UIModalTransitionStyleCoverVertical;
[self presentModalViewController:cv animated:YES];
[cv release];
}
Now problem is that this view is loading in whole screen so that I am not able to access tab bar.
I have set the frame for this view and the view is loading in this frame,
-(void)viewWillAppear:(BOOL)animated
{
self.view.frame = CGRectMake(0, 0, self.view.frame.size.width, 400);
}
but in remaining part white screen is appearing means tab bar is not accessible.
I want that whatever will be load at any time tab bar should be always accessible.
Please help me out.

Add
cv.modalPresentationStyle = UIModalPresentationCurrentContext;

Have you tried using UINavigationController inside your tabbar to dig inside your UIViewControllers??
for Ref : Adding NavigationController to Tabbar
do you really need a viewController Class for what you are trying to display??
if der's no core functionality being used, i think it will be much easier with UIView.
Happy Coding :)

Related

How to present resized UIViewController in UITableViewController - iPhone

I have a UITableViewController with multiple rows, when a row is pressed, I would like to present a ViewController, which has small view with Facebook and twitter buttons, on top of the table view ( the tableview still can be seen).
Although, I have resized the view of the ViewController in storyboard and have unchecked "resize view from nip" but when the ViewController is presented, its view appears as full screen.
I tried to add it as subview but then it is just added to the first row of the tableView.
can you please tell me what I'm doing wrong?
Thank you.
You mighty try something like the following:
1) Initialise your facebook view controller
2) Add your facebook view controller as a child view controller:
[self addChildViewController:self.facebookController];
3) Set the required frame:
[self.facebookController.view setFrame:CGRectMake(x, y, w, h)];
4) Add the facebook controllers view as necessary
[self.requiredView addSubview:self.facebookController.view];
I haven't tried this so I don't know if it works, especially since I haven't done anything with Storyboards yet. It's still worth a try.
If you only want to share info you can use UIActivityViewController,
//Include an array of things being attached to the ActivityViewController
//The Array cannot be nil, you must provide something. Either an image or text or both
NSArray *activityItems = #[#"Hello Share",[UIImage imageNamed:#"someImage"]];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil];
activityViewController.excludedActivityTypes = #[UIActivityTypePostToWeibo, UIActivityTypeAssignToContact ]; // means this item you dont want to show while sharing
[self presentViewController:activityViewController animated:YES completion:NULL];

Scroll to top when tapping the status bar

I got a view controller (lets call it MainViewContoller) that's present 3 different tables (one in a time), user can tap a segment control to switch between those tables.
To present those 3 tables, MainViewContoller has 3 other view controllers (A, B and C), each has a UITableView as a subview and handle it's own data.
When a MainViewContoller is loaded, it initiate controllers A, B and C, and add their tableViews to it's view:
- (void)viewDidLoad {
[super viewDidLoad];
ViewControllerA *vcA = [ViewControllerA alloc] init];
[self.view addSubview:vcA.view];
ViewControllerB *vcB = [ViewControllerB alloc] init];
[self.view addSubview:vcB.view];
ViewControllerC *vcC = [ViewControllerC alloc] init];
[self.view addSubview:vcC.view];
}
So for example when user tap the segment control and choose A, the MainViewContoller hide tables B and C, and unhide table A. Something like this:
if (userTapOnA) {
self.viewControllerA.tableView.hidden = NO;
self.viewControllerB.tableView.hidden = YES;
self.viewControllerC.tableView.hidden = YES;
}
The problem:
When user tap the status bar I want that the current visible table will scroll to top.
This behavior is pretty basic and one gets it for free when using a regular view controller, but as you can see my view controller is not regular.
I suppose that by using other controllers view as MainViewContoller view I break the default behavior, so my MainViewContoller doesn't handle the status bar tap.
Someone got an idea how to solve that?
This is directly from the UIScrollView header file:
/* When the user taps the status bar, the scroll view beneath the
touch which is closest to the status bar will be scrolled to top, but
only if its scrollsToTop property is YES, its delegate does not
return NO from shouldScrollViewScrollToTop, and it is not already at
the top. On iPhone, we execute this gesture only if there's one
on-screen scroll view with scrollsToTop == YES. If more than one is
found, none will be scrolled. */
#property(nonatomic) BOOL scrollsToTop; // default is YES.
So in your case, set all scrollsToTop to NO, except the one you want to enable at that particular moment.
You should register your nested controllers as child controllers.
[self addChildViewController:vcA];
[self addChildViewController:vcB];
[self addChildViewController:vcC];
I'm not sure if this will help to solve your issue, but that's the right way to do it.

how to create pinterest style hiding/unhiding nav/tab bar?

How do I create a hiding/unhiding nav bar like what pinterest and many other apps is doing? I know the basic idea is to use the UIScrollView delegate and detect whether I am scrolling up or down and show the nav bar based on that. So should I also adjust the navcontroller view height if the nav bar is hidden? How does this work?
I have a sample project located on github that does exactly the pinterest/piictu style 'hide the UINavigationController / UITabBarController stuff'
https://github.com/tonymillion/ExpandingView
I've tried https://github.com/tonymillion/ExpandingView and ran into a bunch of issues.
I ended up rolling my own navigation controller to get all the animations synced and used this scrollview code to figure out if I should expand or contract. iOS >=5.0
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
MyCustomNavController* navController = (MyCustomNavController*)self.parentViewController;
if( [scrollView.panGestureRecognizer translationInView:self.view].y < 0.0f ) {
[navController setExpanded:YES animated:YES];
} else if ([scrollView.panGestureRecognizer translationInView:self.view].y > 0.0f ) {
[navController setExpanded:NO animated:YES];
}
}
I would probably try to create my own root controller with scrollbar as main view and put navigation controller's view into it. You can't use scrollbar inside navbar view then but I believe you don't need it in this very case.
If this approach doesn't work I would probably create my own controller that mimic navigation controller appearance.

How can i create a global navigation stack?

I want a global navigation stack. When the user changes tabs or navigates to a new view in the same tab, I want to push the new view onto the global navigation stack. I want the back button in the navigation bar to go back to the previous view, which is sometimes a different tab, and sometimes a different view in the same tab.
To achieve this effect, you could ditch the UITabBarController - and emulate the bar by using a custom view or customizing the standard UIToolbar.
Have one navigation controller with, with your customized toolbar always visible, and when buttons are tapped on it, just push the views you want onto the navstack.
You want all the UIViewController's in the UITabBarController to be loaded into the same UINavigationController?
So something like this:
___ RootViewController ___
| |
UINavigationController UITabBarViewController
instead of
RootViewController
|
_________ UITabbarViewController _____________________
| | |
UINavigationController UINavigationController UINavigationController
You should try "experimenting" with your own custom UITabBar
I suggest you to create a global array (NSMutableArray) that will hold NSInvocation objects. So every time you push view controller you need to create NSInvocation with navigation controller as target and popViewConrollerAnimated: as selector. If you're tapping the tab bar item you need to set tab bar controller as target and setSelectedViewController: as selector. You should also specify current view controller as parameter using
- (void)setArgument:(void *)buffer atIndex:(NSInteger)index
Then every time you pop your global stack you need just call [myLastInvocation invoke];
I Had similar issue. I did it like this :
To change the tab, use : say, you want to go at tab 2 and its 3rd view controller
self.tabBarController.selectedIndex = 2;
[self.tabBarController.delegate tabBarController:self.tabBarController didSelectViewController:
[[[self.tabBarController.viewControllers objectAtIndex:2] viewControllers] objectAtIndex:3]];
you could achieve the same by setting the left bar button of your UINavigationController as the button of your choice, Handle the action method and invoke the appropriate tabbar button on click event.
You need to do all that in your root view controller ...
ADDED:
You could not get the back button on the root view controllers (Navigation controllers;s root view associated with your tabbar instance) just by pressing the tabbar button.
you need to find the way to achieve this as you are not getting this from iOS So The movement you press the tabbar button your need to have the variable that store the previous selected index and a method that give the information for any tabbar by just passing the index ... So by using these two you could set the title of your left bar button of navigation bar and return to the previous tab by assigning the appropriate action method to the left bar button ...
I got it working. In my experience I was needed to have mainTabBarController and detailedNavigationController as two root controllers.
Those two methods of UIApplicationDelegate class work perfect:
- (void) showDetailedTab
{
CGRect normalRect = self.window.bounds;
CGRect rightRect = CGRectOffset(normalRect, normalRect.size.width, 0);
CGRect leftRect = CGRectOffset(normalRect, -normalRect.size.width, 0);
detailedNavigationController.view.frame = rightRect;
mainTabBarController.view.frame = normalRect;
[self.window addSubview:mainTabBarController.view];
[self.window addSubview:detailedNavigationController.view];
[UIView animateWithDuration:0.35 delay:0.0 options:UIViewAnimationCurveEaseOut
animations: ^{
detailedNavigationController.view.frame = normalRect;
mainTabBarController.view.frame = leftRect;
}
completion: ^(BOOL finished){
[mainTabBarController.view removeFromSuperview];
}];
}
- (void) showMainTabBar
{
CGRect normalRect = self.window.bounds;
CGRect rightRect = CGRectOffset(normalRect, normalRect.size.width, 0);
CGRect leftRect = CGRectOffset(normalRect, -normalRect.size.width, 0);
mainTabBarController.view.frame = leftRect;
detailedNavigationController.view.frame = normalRect;
[self.window addSubview:mainTabBarController.view];
[self.window addSubview:detailedNavigationController.view];
[UIView animateWithDuration:0.35 delay:0.0 options:UIViewAnimationCurveEaseOut
animations: ^{
mainTabBarController.view.frame = normalRect;
detailedNavigationController.view.frame = rightRect;
}
completion: ^(BOOL finished){
[detailedNavigationController.view removeFromSuperview];
}];
}
I think this solution is better then emulating of tab bar, since it doesn't break UIViewContoller's life cycle.

Layout Multiview Rotated iPhone App with a Toolbar

I have a multiview app with a Toolbar. The Root view controller controls the toolbar, but the other views have their own view controller class. I use code like this to load the views:
-(IBAction)loadBand1Start:(id)sender{
[self clearView];
Band1Start *band1Controller = [[Band1Start alloc] initWithNibName:#"Band1Start" bundle:nil];
self.band1Start = band1Controller;
[band1Controller release];
[self.view insertSubview:band1Start.view atIndex:0];
if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)) {
band1Start.view.frame=CGRectMake(0, 0, 480.0, 260.0);
} else {
band1Start.view.frame=CGRectMake(0, 0, 320.0, 400.0);
}
}
The IF statement is to make it load in the correct orientation. Without this, although it rotates ok, it always loads in Portrait, even if the phone is in landscape.
Autosize and Auto Rotate works. I used IB to build my nibs in portrait. When the phone is rotated to landscape, they do rotate and resize, however with some nibs, the rotated layout does not look right. There is overlaps etc, which is a common problem, and I know can be fixed using CGRectMake.
However, it does not matter where I put the CGRectCode, it does not execute. I have tried putting it in willRotateToInterfaceOrientation, willAnimateRotationToInterfaceOrientation, and viewWillAppear, but the rotated layout is not changed.
If I use the code below to switch views, the rotated layout is how I want it, but the toolbar does not appear:
-(IBAction)loadBand1Start:(id)sender{
[self clearView];
Band1Start *band1Controller = [[Band1Start alloc] initWithNibName:#"Band1Start" bundle:nil];
[self presentModalViewController:band1Controller animated:NO];
[band1Controller release];
}
I think this is because the view controller for the toolbar needs to be the root view controller for the toolbar to appear, but only the root view controller receives the orientation change notifications.
So if I keep my toolbar controller as the root view controller, the subview's controller does not receive the orientation notifications, so does not execute my CGRectMake code, but if I make the subview's controller the root view controller, it receives the notifications ok, but the toolbar does not appear because it's controller is not the root controller.
Am I correct about the problem here? Is there a way around it?