How to navigate back from UISplitViewController IOS 5? - objective-c

I have 6 views in which I am placing the UISplitViewController at 4th position (i.e.the 4th view). Now when I navigate from 3rd view to 4th view (i.e. ViewController to SplitView) I want to come back to 4th view to 3rd view (i.e. SplitView to ViewController).
I am using the below code to show the UISplitViewController when I am navigating from 3rd view to 4th view.
MasterViewController *masterViewController = [[MasterViewController alloc] initWithNibName:#"MasterViewController" bundle:nil];
UINavigationController *masterNavigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];
DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController:detailViewController];
masterViewController.detailViewController = detailViewController;
self.splitViewController = [[UISplitViewController alloc] init];
self.splitViewController.delegate = detailViewController;
self.splitViewController.viewControllers = [NSArray arrayWithObjects:masterNavigationController, detailNavigationController, nil];
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication]delegate];
appDelegate.window.rootViewController = self.splitViewController;
Now I have created a toolbar in my navigation bar programmatically and placed a back button. Below is the code what I have tried to pop the view back to viewcontroller. (i.e. from SplitView to ViewController).
-(IBAction)backbtn:(UIBarButtonItem *)sender
{
// RepresentativeAccount<UISplitViewControllerDelegate> *represent = [[RepresentativeAccount alloc]initWithNibName:#"RepresentativeAccount" bundle:nil];
// //[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:2] animated:YES];
// [[self.splitViewController.viewControllers objectAtIndex:0]popToViewController:represent animated:YES];
}
Please help thanks.

Reference: View Controller Catalog for iOS
A split view controller must always be the root of any interface you
create.
In other words, you must always install the view from a UISplitViewController object as the root view of your application’s window.
The panes of your split view interface may then contain navigation
controllers, tab bar controllers, or any other type of view controller
you need to implement your interface.
Split view controllers cannot be presented modally.
So, what you are attempting is incorrect, and in fact your app may get rejected by Apple.

Related

UITabBarController is running parallel with my splashsceen

I have a UITabBarController container 4 view controllers and two other view controllers as SplashScreenVC and LoginScreenVC as i have set UINavigationViewController as root view controller and initiate splash screen with the help of navigation controller in my storyboard but when i actually run the app tabBarController and splash screen both run simultaneously. I want to load all of the views of the tab bar to be load after the splash screen and submission of login details.
Here is my code where i set root view controller.
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
HomeViewController *homeVC = [[HomeViewController alloc]init];
homeVC.title = #"Home";
NotificationViewController *notificationVC = [[NotificationViewController alloc]init];
notificationVC.title = #"Notifications";
ProfileViewController *profileVC = [[ProfileViewController alloc]init];
profileVC.title = #"Profile";
SelfiesCollectionViewController *selfiesCollectionVC = [[SelfiesCollectionViewController alloc]init];
selfiesCollectionVC.title = #"Selfie Collection";
homeVC = [storyBoard instantiateViewControllerWithIdentifier:#"HomeViewController"];
profileVC = [storyBoard instantiateViewControllerWithIdentifier:#"ProfileViewController"];
notificationVC = [storyBoard instantiateViewControllerWithIdentifier:#"NotificationViewController"];
selfiesCollectionVC = [storyBoard instantiateViewControllerWithIdentifier:#"SelfiesCollectionViewController"];
self.tabBarController = [[UITabBarController alloc]init];
self.tabBarController = [storyBoard instantiateViewControllerWithIdentifier:#"UITabBarController"];
self.tabBarController.viewControllers = #[homeVC,notificationVC,profileVC,selfiesCollectionVC];
UINavigationController *navigationVC = [[UINavigationController alloc]init];
navigationVC = [storyBoard instantiateViewControllerWithIdentifier:#"UINavigationController"];
[self.window setRootViewController:navigationVC];
You need to do following things.
1)If you are working in Xcode 7 onwards, You have special storyboard for splash screen. You can set your image in that storyboard.
What do you exactly need tab bar controller or navigation controller?
According to my assumption you need navigation controller for login controller. If my assumption is true then you have to create navigation controller's object in following way
UINavigationController *navigationVC = [[UINavigationController alloc]initWithRootViewController:LoginScreenVC];
now you have to add this navigationVc in your tabBarController's viewControllers array. and instead of setting navigationVc as root controller of you window, you can set tab bar as root controller
[self.window setRootViewController:self.tabBarController];
Suggestion: If you are using storyboard you don't have to write all these lines. You can do it very easily in your storyboard file by using segues.
You should not alloc and init your tabBarController before or the need.
In your you need to make a public method like below.
Remove the allocation and initiation of tabBarController from application launchWithOption method
-(void)userDidLoggedIn{
self.tabBarController = [[UITabBarController alloc]init];
self.tabBarController = [storyBoard instantiateViewControllerWithIdentifier:#"UITabBarController"];
self.tabBarController.viewControllers = #[homeVC,notificationVC,profileVC,selfiesCollectionVC];
[self.window setRootViewController:self.tabBarController];
}
Now simply call this method on the success of login button like this..
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate userDidLoggedIn];

PresentModalViewController not showing TabBar

I'm trying to go from one xib to another and I'm using TabBar.
When I move from xib to xib with PresentModalViewController I lose the TabBar.
When I use this way, it fail (like force close in android):
FirstViewController *fvc = [[FirstViewController alloc]initWithNibName:#"FirstViewController" bundle:nil];
[fvc setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
fvc.userSelectedLatitude = saveLatitude;
fvc.userSelectedLongitude = saveLongtitude;
UITabBarController *tabControl = [[UITabBarController alloc] initWithNibName:fvc bundle:nil];
[self presentModalViewController:tabControl animated:NO];
When I use:
UITabBarController *tabControl = [[UITabBarController alloc] initWithNibName:#"FirstViewController" bundle:nil];
I get black screen with TabBar.
Since it all fail I guess it is not the right way.
So, what is the right way to do it?
The code above crashes because you are trying to pass a view controller instead of an NSString object in the initWithNibName:bundle: method.
The way to do it depends of what you really want to do. Do you want to present the xib in a modalViewController with or without a tabBar?, or simply present the view controller modally?.
UPDATE:
Fine, you have to create first your view controllers associated to each tabBar button (like you have been doing until now), after, add these view controllers to your tabBar and then present the tabBarController modally. Like this:
FirstViewController *fvc = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
fvc.userSelectedLatitude = saveLatitude;
fvc.userSelectedLongitude = saveLongtitude;
UITabBarController *tabControl = [[UITabBarController alloc] init];
[tabControl setViewControllers:[NSArray arrayWithObjects:fvc, nil]];
[tabControl setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[self presentModalViewController:tabControl animated:NO];
I think this code should work. So, try it and tell us if something goes wrong.
With UITabBarController, there is no need to manually present viewControllers or call code to switch the views. This is handled for you.
All you need to do is set the viewControllers property of the UITabBarController. Like so:
[tabBarController setViewControllers:[NSArray arrayWithObjects:view1, view2, nil]];

How do I implement a UINavigationController in this case?

current version of my project :
I have 5 different UIViewControllers in my app. I've set my
FirstViewController to be the Initial View Controller using the
Attributes Inspector. I move back and forth from one ViewController to
another by using buttons to which I assign modal segues, from one
ViewController to another, using the StoryBoard
What I want to change:
I want to keep the navigation buttons obviously, delete the modal segues and use
a UINavigationController instead. If I understand the concept
correctly, when using a UINavigationController I need to go into each
UIButton-IBAction and at the very end of the method I have to push the next
ViewController I want to move to, onto my NavigationController (do I also
have to pop the current one first?). However, I can't figure out how
to implement all that correctly.
What I've done so far:
I removed all modal segues from the storyboard and kept the navigation buttons along with their corresponding IBActions
I unchecked the box in the Attributes Inspector that was making my FirstViewController the initial View Controller of my app
I went into my AppDelegate.m and tried to create the Navigation Controller there and make my FirstViewController be the RootViewController
MyAppDelegate.m
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIViewController *myFirstViewController = [[FirstViewController alloc] init];
UINavigationController *myNavigationController = [[UINavigationController alloc] initWithRootViewController:myFirstViewController];
[myNavigationController pushViewController:myFirstViewController animated:YES];
// Override point for customization after application launch.
return YES;
}
I then tried to test if the above was working by going into the IBAction of a
navigation button on my FirstViewController and implemented the
following in order to move to my SecondViewController when the
button is pressed :
FirstViewController.m
- (IBAction)goRightButton:(UIButton *)sender
{
// some code drawing the ButtonIsPressed UIImageView on the current View Controller
UIViewController *mySecondViewController = [[SecondViewController alloc] init];
[self.navigationController pushViewController:mySecondViewController animated:YES];
}
but nothing happens. What am I doing wrong ?
You are not linking your XIB file. Please add your navigation controller as
UIViewController *myFirstViewController = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
navigationController = [[UINavigationController alloc] initWithRootViewController:myFirstViewController];
Use following code to move from one view to another
UIViewController *mySecondViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
[self.navigationController pushViewController:mySecondViewController animated:YES];
If you are using a storyboard, you should just drag in the navigation controller there and hook it up to your app delegates. As long as it is the main storyboard, and you have identified a view controller to load first, you do not need to load any views in your app delegate.
In order to push a view programmatically that's in a storyboard, you need to do something like the following:
//bundle can be nil if in main bundle, which is default
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
MyCustomViewController *customVC = (MyCustomViewController *)[mainStoryboard instantiateViewControllerWithIdentifier:#"customVC"];
//standard way
[self.navigationController pushViewController:customVC animated:YES];
//custom animation
[UIView transitionWithView:self.navigationController.view duration:0.5 options:UIViewAnimationOptionTransitionCurlUp animations:^{
[self.navigationController pushViewController:customVC animated:NO];
} completion:nil];
You identify the view controller with the identifier you add in the storyboard editor. Below are some screenshots to help show what I mean.

Problem with pushing multiple view controllers in one code block

In order to restore my iphone application to a paticular view controller, i am trying to push the view controllers one after another in the application delegate.
The order of the view controllers on the stack initially is :
1. Root View Controller
2. First View Controller
3. Second View Controller
What I want is that when my application launches, it should go directly to the Second view controller. For this I have written the following code :
[self.navigationController popToRootViewControllerAnimated:NO];
RootViewController *rootViewController = [[RootViewController alloc]initWithNibName:#"RootViewController" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:rootViewController animated:NO];
FirstViewController *firstViewController=[[NSClassFromString(#"FirstViewController") alloc] initWithNibName:#"FirstViewController" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:firstViewController animated:NO];
SecondViewController *secondViewController=[[NSClassFromString(#"SecondViewController") alloc] initWithNibName:#"SecondViewController" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:secondViewController animated:NO];
The problem is that when the Second view controller loads, its back button is named "Back" , instead of the title of the first view controller. I have not explicitly set a back button in the third view controller.
Regards
You should set the title of the UINvaigationItem for FirstViewController, which will be aditionally seen in the center of navigation bar.

How combine TabBar + Navigation with XCode

I'm triying to combine a TabBar + Navigation app.
I have 5 tab bars, 4 are listing of stuff and drill down to details views.
I try to follow this tutorial:
http://www.iphonedevforums.com/forum/iphone-sdk-development/124-view-controller-problem.html
But always get a blank view.
This is what I do, with a clean project:
I start with a TabBar template app.
I put 5 tab bar buttons.
I create a controller like:
#interface FirstViewController : UINavigationController {
}
I put the main window.xib on tree mode & change the selected first view to FirstViewController
I select the TabBar Controller in Interface builder, go to TabBar Attributes & change the class to navigation controler.
Select the fist view & put the nib name "SecondView"
In response, I get a blank screen.
I must add that I wanna navigate from the details views, no from the main windows.
i.e in the main window tab bar 1 is the list of people. I select a person then wanna navigate to the detail window.
First, you never want to subclass UINavigationController or UITabBarController.
Second, I did not quite get what you did, but a correct sequence to create a navigation controller inside a tab bar controller is something like this:
// in MyAppDelegate.h
UINavigationController *nc1, *nc2;
FirstTabRootViewController *vc1;
SecondTabRootViewController *vc2;
UITabBarController *tbc;
// in MyAppDelegate.m
nc1 = [[UINavigationController alloc] init];
vc1 = [[FirstTabRootViewController alloc] initWithNibName:nil bundle:nil];
vc1.tabBarItem.title = #"Tab 1";
vc1.tabBarItem.image = [UIImage imageNamed:#"tab1.png"];
vc1.navigationItem.title = "Tab 1 Data";
nc1.viewControllers = [NSArray arrayWithObjects:vc1, nil];
nc2 = [[UINavigationController alloc] init];
vc2 = [[SecondTabRootViewController alloc] initWithNibName:nil bundle:nil];
vc2.tabBarItem.title = #"Tab 2";
vc2.tabBarItem.image = [UIImage imageNamed:#"tab2.png"];
vc2.navigationItem.title = "Tab 2 Data";
nc2.viewControllers = [NSArray arrayWithObjects:vc2, nil];
tbc = [[UITabBarController alloc] init];
tbc.viewControllers = [NSArray arrayWithObjects:nc1, nc2, nil];
Note that it's your view controller that controls the text/icon in the tab bar and in the navigation bar. Create a UINavigationController instance for each of your tabs; UINavigationController contains a stack of view controllers (see viewControllers property) which should contain at least one item — your root controller for that tab. Also create an UITabBarController to manage the tabs.
Of course, you can (and probably should) use interface builder instead of code to instantiate the mentioned classes and set the properties. But it's important that you understand what happens behind the scenes; interface builder is nothing more than a convenient way to instantiate and set up objects.
Hope this is helpful; please refine your question if it's not.
Still getting the blank screen On Starting the application after implementing the above code. Where i 'm writing it wrong.
nc1 = [[UINavigationController alloc] init];
nc2 = [[UINavigationController alloc] init];
vc1 = [[FirstRootViewController alloc]initWithNibName:#"FirstRootViewController" bundle:nil];
vc1.tabBarItem.title = #"Item 1";
vc1.tabBarItem.image= [UIImage imageNamed:#"home.png"];
vc1.navigationItem.title = #"Tab1 Data";
nc1.viewControllers = [NSArray arrayWithObjects:vc1,nil];
vc2 = [[SecondRootViewController alloc]initWithNibName:#"SecondRootViewController" bundle:nil];
vc2.tabBarItem.title = #"Item 2";
vc2.tabBarItem.image= [UIImage imageNamed:#"home.png"];
vc2.navigationItem.title = #"Tab2 Data";
nc2.viewControllers = [NSArray arrayWithObjects:vc2,nil];
tbc = [[UITabBarController alloc]init];
tbc.viewControllers = [NSArray arrayWithObjects:nc1,nc2,nil];
[window addSubview:tbc.view];
[window makeKeyAndVisible];
Here is an tutorial that I was able to get working.
I also read the official SDK documentation on the topic: Combining Tab Bar and Navigation Controllers. Since I'm still learning, the tutorial helped me more than the docs.
NOTE: in the tutorial, i don't think you need to subclass UINavigationController, and I'm experimenting with this idea now.
I tried to create an iphone application with UITabBarController and some UINavigationController inside it and faced the same problems as "mamcx". With your example-code i get it to run :) Thanks a lot.
Here is how it works for me.
// YOURS
fourthNavigation = [[UINavigationController alloc ] init ];
fourthViewController = [[[FourthTabRootController alloc] initWithNibName:#"FourthView" bundle:nil] autorelease];
fourthNavigation.tabBarItem.title = #"YOURS";
fourthNavigation.viewControllers = [NSArray arrayWithObjects:fourthViewController, nil];
// Add self-defined UIViewControllers to the tab bar
tabBarController.viewControllers = [NSArray arrayWithObjects:firstNavigation,secondNavigation, thirdNavigation, fourthNavigation, nil];
// Add the tab bar controller's current view as a subview of the window
[window addSubview:tabBarController.view];
The other UINavigationControllers "firstNavigation, ... " are created the same way.
I load the view elements from nib-files that are connected to my subclassed UIViewController classes. You dont need to add a NavigationBar in the IB to your view, cause the UINavigationController has allready one. So you only need to set the title in "initWithNibName"
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
// Custom initialization
self.title = #"YOURS";
}
return self;
}
I hope that helps.
Check out "Adding a Navigation Controller to a Tab Bar Interface" under View Controller Catalog for iOS which take you step by step into how exactly this can be achieved