Why won't self.navigationController pushViewController work? - ios

I have a
UIViewController-> UINavigationBar + UITableView
Just a bit more explanation
I made it through UIBuilder..
1: Created a New UIViewController with XIB-file
2: Using UIBuiler i put a UINavigationController
3: Then i put UITableView underneath the navigationBar
so it gave me..
A: UIViewController-> UINavigationBar + UITableView
Now i am loading the data in UITableView from a Webservice which is working fine.
I again made a xib with sam config which is
B: UIViewController-> UINavigationBar + UITableView
So now when i try to push view B on view A using below code...it wont at all work...
SelectSiteViewController *siteViewController = [[SelectSiteViewController alloc] initWithNibName:#"SelectSiteViewController" bundle:nil];
[self.navigationController pushViewController:siteViewController animated:YES];
When i checked the UINavigationController *nav = self.navigation
nav is 0x0 that is i assume NIL.
Can anybody tell me whats wrong in here.. why is it nil...and how can i make it work..
Thanks a Lot....I would really appreciate any help

In UIBuilder verify that UINavigationController is referenced by the File's owner.

Got it.
I changed the Architecture a little bit.
I made a New UIViewController class with its xib. And coded new UINavigationController.
- (void)viewDidLoad {
[super viewDidLoad];
UINavigationController *navigationController
navigationController = [[UINavigationController alloc] init];
[self.view addSubview:navigationController.view];
switch (whichViewController) {
case 1:
viewController = [[xxxx alloc] init];
break;
case 2:
viewController = [[xxx1 alloc] init];
break;
default:
break;
}
[navigationController pushViewController:viewController animated:NO];
[viewController release];
}
And pushing the view in the Switch Statement....
I hope this makes sense ......
Thanks jamihash

So you are adding the tableview to the navigation controller right? This is how:
tableView = [[UITableViewController alloc] initWithStyle:UITableViewStylePlain];
navigationController = [[UINavigationController alloc] init];
[navigationController pushViewController:tableView animated:NO];
The tableview gets added as the rootview to the navigation controller. And then on selecting a row if you wish to push another viewcontroller use the
self.navigationController pushViewController: newViewController animated:YES];
inside the didSelectRowAtIndex method.
NOTE: its UITableViewController *tableView and UINavigationController *navigationController by declaration. So code accordingly for your table.

why UIViewController-> UINavigationBar + UITableView ?
I suggest you another approach
->UITableViewController A -> Embedded with a Navigation Controller, then after populate tableview you can pass data to
->UITableViewController B by
[[self storyboard]instantiateViewControllerWithIdentifier:#"ControllerB"];
then, in storyboard, drop a tableView B and in Identity->storyboard Id put some id.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *sUrl= #"<#string#>";
if (indexPath.row == 0) sUrl= #"http://www.apple.com/";
if (indexPath.row == 1) sUrl= #"http://www.google.com/";
if (indexPath.row == 2) sUrl= #"http://www.times.uk/";
NSMutableArray *selectedObject = [arrayOpenMale objectAtIndex:0];
NSLog(#"%# is the selected object.",selectedObject);
SeriesAdetailVC *dvc = [[self storyboard]instantiateViewControllerWithIdentifier:#"DetailView"];
dvc.strings7 = [NSURL URLWithString:sUrl];
[self.navigationController pushViewController:dvc animated:YES];
}
hope help

Related

self.navigationController is (null) in TableViewController which is on a TabBarController

I'm trying to create a small app in iOS. After the Login Page, I have a TabBarController and the first tab in it is a TableViewController. In didSelectRowAtIndexPath I'm trying to push one view controller for every selected row. The same view controller but self.navigationController is (null) when I print it using an NSLog and I'm not able to push the ViewController. HELP!!
Here's the sample Code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here, for example:
// Create the next view controller.
PlayerDetailsViewController *detailViewController = [[PlayerDetailsViewController alloc] initWithNibName:#"PlayerDetailsViewController" bundle:nil];
detailViewController.myImg.image=[UIImage imageNamed:[self.arrNames objectAtIndex:indexPath.row]];
detailViewController.name.text=[self.names objectAtIndex:indexPath.row];
detailViewController.year.text=[self.draft objectAtIndex:indexPath.row];
detailViewController.height.text=[self.height objectAtIndex:indexPath.row];
detailViewController.weight.text=[self.weight objectAtIndex:indexPath.row];
detailViewController.pro.text=[self.pro objectAtIndex:indexPath.row];
detailViewController.ppg.text=[self.ppg objectAtIndex:indexPath.row];
detailViewController.apg.text=[self.apg objectAtIndex:indexPath.row];
detailViewController.rpg.text=[self.rpg objectAtIndex:indexPath.row];
NSLog(#"%#",self.navigationController);
[self.navigationController pushViewController:detailViewController animated:YES];
}
UPDATE: I got the navigationController to work but now, the data in the pushed view(PlayerDetails) in blank!!
It's just wrong that you haven't nested your firstViewController inside UINavigationController.
So I guess your code will be seems like this when creating UITabViewController.
[tabVC setViewControllers:[vc1,vc2,nil]];//tabVC = UITabViewController
And it need to be changed something like below;
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc1];
[tabVC setViewControllers:[nav,vc2,nil]];
Assume that the instance of UITabBarController is tabVC and the instance of UITableViewController is tableVC.
UINavigationController *nav = [[UINavigationController alloc initWithRootViewController:tabVC];
or
UINavigationController *nav = [[UINavigationController alloc initWithRootViewController:tableVC];
[tabVC setViewControllers:#[nav]];
Both will fix your problem.

iOS - how to set a navigation bar item in view controller?

I'm new to Objective-C and I want to add a UINavigationBar on my CatrgoryBIDViewController. I have proceed UIButton in InstructionBIDViewController.m file that should navigate to CatrgoryBIDViewController. Here is the function code:
- (IBAction)proceed:(id)sender {
viewControllercat =
[[CatrgoryBIDViewController alloc]
initWithNibName:#"CatrgoryBIDViewController"
bundle:nil];
UINavigationController *nav =
[[UINavigationController alloc]
initWithRootViewController:self.viewControllercat];
//[self.navigationController pushViewController:viewControllercat animated:YES];
[self.navigationController setNavigationBarHidden:NO animated:YES];
}
But it is not setting the UINavigationBar.
You should read the documentation here to understand the way a NavigationController is working. For your case:
If your current ViewController (where your proceed-method is implemented) has a NavigationController (is child of it), you can push another ViewController onto the stack of that NavigationController with
[self.navigationController pushViewController:viewControllercat animated:YES];
In this case you do not need to initialize another NavigationController, but in your CatrgoryBIDViewController in viewWillAppear you need to make the NavigationBar visible if it was not before already with
[self.navigationController setNavigationBarHidden:NO animated:YES];
If your current ViewController does not have a NavigationController, you can not push another ViewController on top of it and can not show the NavigationBar of it (although you can create your own NavigationBar and add it to the View of the ViewController, but without the usual Navigation-behaviour embedded).
If you open your ViewController programmatically (e. g. from the AppDelegate) you are correct to do so by your call:
viewControllercat = [[CatrgoryBIDViewController alloc] initWithNibName:#"CatrgoryBIDViewController" bundle:nil];
UINavigationController *nav=[[UINavigationController alloc] initWithRootViewController:self.viewControllercat];
My apologies - After having reread your question, I am going to tweak my answer some.
-(IBAction)proceed:(id)sender
{
viewControllercat = [[CatrgoryBIDViewController alloc] init];
UINavigationController * nc =
[[UINavigationController alloc] initWithRootViewController:vc];
// We now need to display your detail view but cannot push it.
// So display modally
[self presentViewController:nc animated:YES completion:Nil];
}
The above should result in your DetailViewController - CategoryBIDViewController being displayed on top of your InstructionBIDViewController and it should have a UINavigationController in it.

MMDrawerController and instantiating many view controllers

This is a specific MMDrawerController question, although probably relates to other iOS drawer controllers out there.
I've got my MMDrawerController working nicely, and can load different view controllers into the 'center' by selecting a row in my drawer tableview.
However, I want to avoid instantiating my view controllers every time I select a menu item in my drawer. It seems inefficient, especially if the user will switch between screens many times during a session. I'm guessing a better way is to store the (instantiated) view controllers I'm using as a variable and to reuse? I have quite a few view controllers to potentially load into the center, each of which will do some 'work' initially in viewDidLoad.
Here is how I am loading a new view controller into the center (in my DrawerViewController.didSelectRowAtIndexPath method):
MyViewConroller * newCenter = [[MyViewConroller alloc] init];
UINavigationController * nav = [[MMNavigationController alloc] initWithRootViewController:newCenter];
if(indexPath.row==0){
[self.mm_drawerController
setCenterViewController:nav
withCloseAnimation:YES
completion:nil];
}
Thoughts/comments about the best approach of loading these view controllers would be appreciated.
This method is working well for me and there is no need to instantiate a new view controller or navigation controller every time the user changes views.
Declare a mutable array to hold your navigation controllers:
#property (nonatomic, strong) NSMutableArray *navigationControllerArray;
Initialise and fill the array with the same number of empty strings as you have view controllers:
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationControllerArray = [[NSMutableArray alloc] initWithObjects:#"",#"",#"",nil];
}
In your UITableViewDelegate, check to see if the object at the selected row is a UINavigationController. If it is not, instantiate a new navigation controller and replace the empty string in your navigation controller array with it.
Set this navigation controller as the center view controller:
#pragma mark - UITableViewDelegate
-(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSObject *navigationController = [self.viewControllerArray objectAtIndex:indexPath.row];
if (![navigationController isKindOfClass:[UINavigationController class]]) {
UIViewController *newViewController;
switch (indexPath.row) {
case 0:
newViewController = (UIViewController *)[[AccountListTableViewController alloc] init];
break;
case 1:
newViewController = (UIViewController *)[[PageDetailViewController alloc] init];
break;
case 2:
newViewController = (UIViewController *)[[LoginViewController alloc] init];
break;
default:
newViewController = (UIViewController *)[[AccountListTableViewController alloc] init];
break;
}
navigationController = (UINavigationController *)[[UINavigationController alloc] initWithRootViewController:(UIViewController *)newViewController];
[self.viewControllerArray replaceObjectAtIndex:indexPath.row withObject:navigationController];
}
[self.mm_drawerController setCenterViewController:(UINavigationController *)navigationController withCloseAnimation:YES completion:nil];
return indexPath;
}

How to load a different view to detail view in split view iOS

I was wondering how I can load a different view into the detailView from rootview..
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) {
SecondViewController *svc = [[SecondViewController alloc] init];
//[self.navigationController pushViewController:svc animated:YES];
}
}
The splitviewcontroller has an array of 2 views one is root view and another one is detail view,and you can change the views in this array. If you alloc and init a view and replace it with either of these two then this view will replace the current view in the splitviewcontroller.
Use this code for loading different views for different cells of rootview. Change rootview's didSelectRowAtIndexPath method as follow:
- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIViewController *localdetailViewController = nil;
if (indexPath.row==0)
{
DetailViewController *detailView=[[DetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
localdetailViewController=detailView;
detailView=nil;
}
if (indexPath.row==1)
{
SecondViewController *secondDetailView=[[SecondViewController alloc] initWithNibName:#"SecondDetailViewController" bundle:nil];
localdetailViewController=secondDetailView;
secondDetailView = nil;
}
UINavigationController *navController=[[UINavigationController alloc] init];
[navController pushViewController:localdetailViewController animated:YES];
YourSplitViewAppDelegate *delegate=[[UIApplication sharedApplication] delegate];
NSArray *viewControllers=[[NSArray alloc] initWithObjects:[delegate.splitViewController.viewControllers objectAtIndex:0],navController,nil];
delegate.splitViewController.viewControllers = viewControllers;
[localdetailViewController release];
[navController release];
}
My solution is using Using Xcode 7.1.1 for a universal app, using Storyboards, Auto Layout and Size Classes, building for iOS 9...
I used a version of Midhun MP's answer... within the current/original (not replacement/new/second) detail view controller's viewDidLoad method:
obviously first import the correct header file for your controller:
#import "NEW_DetailViewController.h"
then within viewDidLoad method:
- (void)viewDidLoad {
[super viewDidLoad];
<<OTHER_CODE>>
if (<<INSERT_THE_LOGIC_YOU_NEED_TO_TRIGGER_THE_REPLACEMENT_DETAIL_VC>>) {
NEW_DetailViewController *viewNewDetailVC = [[NEW_DetailViewController alloc] initWithNibName:#"NEW_DetailViewController" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc] init];
[navController pushViewController:viewNewDetailVC animated:YES];
NSArray *arraySplitViewControllers = [[NSArray alloc] initWithObjects:[self.splitViewController.viewControllers objectAtIndex:0],navController,nil];
self.splitViewController.viewControllers = arraySplitViewControllers;
}
}
NOTE I could make this code work without loading a XIB file, building the entire replacement detail VC in code, with [[UIViewController alloc] init] instead of [[NEW_DetailViewController alloc] initWithNibName:#"NEW_DetailViewController" bundle:nil], but was frustrated that I could not make the XIB file load, so I persisted...
I attempted many variations from many different SO answers in attempting to solve this problem of successfully loading a XIB file as the replacement detail view controller in a split view controller.
Finally this answer by Travis M gave me the hint I needed...
Delete all the efforts you have attempted to date to create a new XIB file and subclass of UIViewController!
Create a new file and make it a subclass of UIViewController. See screenshot:
IMPORTANT ensure you check the checkbox "Also create XIB file".
You don't need to modify the new subclass of UIViewController, unless you'd like to code up the contents of the view. I only needed to add in a UILabel for my solution and I did this using Interface Builder.
Make sure you reference the replacement view controller NEW_DetailViewController in code as per my example above.
That's it!
In your XIB file you should end up with the following:

How can we change views in a UISplitViewController other than using the popover and selecting?

I have done a sample app with UISplitViewController studying the example they have provided. I have created three detailviews and have configured them to change by the default means. Either using the left/master view in landscape AND using the popover in the portrait orientation.
Now I am trying to move to another view(previous/next) from the currentView by using left/right swipe in each view. For that, what I did was just created a function in the RootViewController. I copy-pasted the same code as that of the tablerow selection used by the popover from the RootViewController. I am calling this function from my current view's controller and is passing the respective index of the view(to be displayed next) from the current view. Function is being called but nothing is happening.
Plz help me OR is anyother way to do it other than this complex step? I am giving the function that I used to change the view.
- (void) rearrangeViews:(int)viewRow
{
UIViewController <SubstitutableDetailViewController> *detailViewController = nil;
if (viewRow == 0) {
DetailViewController *newDetailViewController = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
detailViewController = newDetailViewController;
}
if (viewRow == 1) {
SecondDetailViewController *newDetailViewController = [[SecondDetailViewController alloc] initWithNibName:#"SecondDetailView" bundle:nil];
detailViewController = newDetailViewController;
}
if (viewRow == 2) {
ThirdDetailViewController *newDetailViewController = [[ThirdDetailViewController alloc] initWithNibName:#"ThirdDetailView" bundle:nil];
detailViewController = newDetailViewController;
}
// Update the split view controller's view controllers array.
NSArray *viewControllers = [[NSArray alloc] initWithObjects:self.navigationController, detailViewController, nil];
splitViewController.viewControllers = viewControllers;
[viewControllers release];
if (rootPopoverButtonItem != nil) {
[detailViewController showRootPopoverButtonItem:self.rootPopoverButtonItem];
}
[detailViewController release];
}
I have googled and found a nice approach. They use a UINavigationController on the detail view to push new views. You could use this same solution for your project.
http://www.cimgf.com/2010/05/24/fixing-the-uisplitviewcontroller-template/

Resources