navigationController = null in TableViewController's pushViewController method (popover) - ios

First of all, sorry for my English.
I'm trying to do an app for iPad with a navigation controller which pushes view controllers when a button "Next" is selected. But I also want to have a popover, called from a button in the nav bar, that allows the user to "jump" from one view controller to another, pushing it with the tableView:didSelectRowAtIndexPath: and the pushViewController:animated: methods, but it's not working.
Summary:
Tab bar -> switches between FirstViewController and SecondViewController (works just fine)
Nav bar (button Next) -> switches between SecondViewController, FirstSlideController and SecondSlideController (it's also good)
Popover -> user selects SecondViewController, FirstSlideController or SecondSlideController (here's the problem!)
Codes:
AppDelegate
UIViewController *viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
UINavigationController *navigationController1 = [[UINavigationController alloc] initWithRootViewController:viewController1];
UIViewController *viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
UINavigationController *navigationController2 = [[UINavigationController alloc] initWithRootViewController:viewController2];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = #[navigationController1, navigationController2];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
TableViewController(popover)'s didSelectRowAtIndexPath method:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row == 0){
FirstSlideController *detailViewController = [[FirstSlideController alloc] initWithNibName:#"FirstSlideController" bundle:nil];
[self.navigationController pushViewController:detailViewController animated:YES];
}
else if(indexPath.row == 1){
SecondSlideController *detailViewController = [[SecondSlideController alloc] initWithNibName:#"SecondSlideController" bundle:nil];
[self.navigationController pushViewController:detailViewController animated:YES];
}
else{
SecondViewController *detailViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
[self.navigationController pushViewController:detailViewController animated:YES];
}
}
SecondViewController (with delegate suggested by maros)
-(void) showPopover:(id) sender
{
TableViewController *PopoverView = [[TableViewController alloc] initWithNibName:#"TableViewController" bundle:nil];
self.popOver = [[UIPopoverController alloc] initWithContentViewController:PopoverView];
self.popOver.delegate = self;
[self.popOver presentPopoverFromBarButtonItem:self.navigationItem.leftBarButtonItem permittedArrowDirections: UIPopoverArrowDirectionUp animated: YES];
}
I tried to print self.navigationController and it says it's null. I'd appreciate any help.
Thank you.

Presnented UIPopoverController is not pushed on the navigation stack in the view controller from which it was presented. It is a separate view controller.
Therefore the navigationController inside the popover is nil.
What I would recommend you is to create a delegate MyNavigationPopoverDelegate (the class that creates a popover (PopoverController). Pass it's instance as an delegate to the TableViewController.
After users clicks on some button inside popover, call delegate's method to processes button clicks (myNavigationPopover:(UIPopoverController*)popover clickedButtonAtIndex:(NSInteger)buttonIndex).
Then maybe dismiss delegate?
and finally change navigation however you want! :)
#protocol MyNavigationPopoverDelegate
- (void) myNavigationPopover:(UIPopoverController*)popover clickedButtonAtIndex:(NSInteger)buttonIndex;
#end
#interface TableViewController : UITableVieController // your viewController in popover
... // your code
#property (nonatomic, weak) NSObject <MyNavigationPopoverDelegate> * delegate;
... // your code
#end
#implementation TableViewController
...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.delegate myNavigationPopover:self clickedButtonAtIndex:indexPath.row];
}
...
#end
// defines that SecondViewController implements the delegate's method
#interface SecondViewController <MyNavigationPopoverDelegate> : UIViewController
// your code
#end
// code where you presenting popover
#implementation SecondViewController
// This is the method that is executed after your button press and it is responsible for presenting a popover
- (void) presentPopover{
...
myPopover.delegate = self; // setting the delegate
[myPopover presentPopoverFromXXX ...]; // however you present it
...
}
- (void) myNavigationPopover:(UIPopoverController*)popover clickedButtonAtIndex:(NSInteger)buttonIndex
{
UINavigationController *currentNavigationController = ; // get the navigation controller from the tab bar
if(buttonIndex == 0){
FirstSlideController *detailViewController = [[FirstSlideController alloc] initWithNibName:#"FirstSlideController" bundle:nil];
[currentNavigationController pushViewController:detailViewController animated:YES];
}
else if(buttonIndex == 1){
SecondSlideController *detailViewController = [[SecondSlideController alloc] initWithNibName:#"SecondSlideController" bundle:nil];
[currentNavigationController pushViewController:detailViewController animated:YES];
}
else{
SecondViewController *detailViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
[currentNavigationController pushViewController:detailViewController animated:YES];
}
}
#end;

Related

Pushing new UIViewController from custom UIPopOver issue

Hello I'm using this library to show my PopOver which contain tableView with searchBar.
The problem is that one user try to select row from the tableView instead dismissing the popOver and displaying the slected row in hole screen I got this :
.
I've tried to use [self.parentViewController.navigationController ...] to push my view but didn't worked.
This is my popOver code (in MainVC.h):
-(IBAction)showPopoverSearch:(id)sender{
UIBarButtonItem *btn = (UIBarButtonItem *) sender;
NSInteger width = 600;
NSInteger height = 400;
SearchViewController *searchVC = [self.storyboard instantiateViewControllerWithIdentifier:#"searchView"];
searchVC.modalInPopover = NO;
UINavigationController* contentViewController = [[UINavigationController alloc] initWithRootViewController:searchVC];
popoverController = [[WYPopoverController alloc] initWithContentViewController:contentViewController];
popoverController.delegate = self;
//popoverController.passthroughViews = #[btn];
popoverController.popoverContentSize = CGSizeMake(width, height);
popoverController.popoverLayoutMargins = UIEdgeInsetsMake(10, 10, 10, 10);
popoverController.wantsDefaultContentAppearance = YES;
[popoverController presentPopoverFromBarButtonItem:btn permittedArrowDirections:WYPopoverArrowDirectionAny animated:YES];
}
And this is the didSelctRow method (SearchViewController.m) :
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main"bundle:nil];
PostReaderViewController *postReaderView =
(PostReaderViewController *)
[storyboard instantiateViewControllerWithIdentifier:#"postReader"];
postReaderView.thePost = [_postsArray objectAtIndex:indexPath.row];
// if ([self.parentViewController.po .popoverController isPopoverVisible])
// [popoverController dismissPopoverAnimated:YES];
[self.navigationController pushViewController:postReaderView animated:YES];
}
To solve this issue I've passed the Navigation controller and popoverController from The parent View MainVC.h to child controller SearchViewController.h and then use those vars to dismiss my PopOvercontroller and push the new VC. Code snippet :
SearchView
#interface SearchViewController : UIViewController
#property (strong, nonatomic) WYPopoverController *parentPopoverVC;
#property (strong, nonatomic) UINavigationController *parentNavigationController;
#end
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
...
[self.parentPopoverVC dismissPopoverAnimated:YES];
[self.parentNavigationController pushViewController:postReaderView animated:YES];
}
MainVC.h
-(IBAction)showPopoverSearch:(id)sender{
SearchViewController *searchVC = [self.storyboard instantiateViewControllerWithIdentifier:#"searchView"];
[searchVC setParentPopoverVC:popoverController];
[searchVC setParentNavigationController:self.navigationController];
[popoverController presentPopoverFromBarButtonItem:btn permittedArrowDirections:WYPopoverArrowDirectionAny animated:YES];
}

Embed navigation controller in modal view contriller programatically

I'm presenting a modal view controller using following code,
[[mInfo objectForKey: kNavigationController] presentViewController:(UIViewController*)modalViewControlr animated:YES completion:nil];
UITableView. On selecting a table view cell I want to navigate it to another UIView called navigatedView.
Is this can be done by embedding self (i.e,modalViewControlr) in navigation Controller and add view (i.e, navigatedView) to a view controller and present it?
for example,
// in modalViewControlr
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//
UINavigationController *passcodeNavigationController = [[UINavigationController alloc] initWithRootViewController:self];
UIViewController *vc = [[UIViewController alloc]init];
[vc.view addSubview:self.navigatedView];
self.navigatedView.frame=vc.view.frame;
[passcodeNavigationController pushViewController: vc animated:YES];
//
}
Please help....
I prefer do it in this way which is easier to understand.
1.Embed the navigationController in AppDelegate:
ModalViewControlr *vc = [[ModalViewControlr alloc]init];
UINavigationController *passcodeNavigationController = [[UINavigationController alloc] initWithRootViewController:vc];
self.window.rootViewController = passcodeNavigationController;
2.Create a new class NavigatedViewControllerand custom the controller in viewDidLoad
Create an UIView call navigatedView
#property (nonatomic, strong) UIView *navigatedView;
-(void)viewDidLoad
{
[super viewDidLoad];
_navigatedView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.navigatedView.backgroundColor = [UIColor redColor];
[self.view addSubView:self.navigatedView];
}
3.Then return to modalViewControlr where you want to push from.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NavigatedViewController *vc = [[NavigatedViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
}

iOS pushViewController is not working

I have a navigation controller, a view controller, and a table view that were all created in my storyboard:
When you touch a certain row in the table view, it SHOULD push a new controller onto the navigation controller, but instead nothing happens. Here is the code:
- (void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath {
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
UINavigationController *controller = (UINavigationController*)[mainStoryboard
instantiateViewControllerWithIdentifier: #"dbNav"];
SubLevelViewController *slController = [[SubLevelViewController alloc] initWithStyle:UITableViewStylePlain];
[controller pushViewController: slController animated: YES];
}
Try
- (void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath {
UINavigationController *controller = self.navigationController;
SubLevelViewController *slController = [[SubLevelViewController alloc] initWithStyle:UITableViewStylePlain];
[controller pushViewController: slController animated: YES];
}
Basically instantiateViewControllerWithIdentifier creates a new instance of the specified view controller each time you call it, so you are pushing the view in a different Navigation controller than the one that is displayed
This worked for me. You have to define index path.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
ServicesModel *service = [services objectAtIndex:indexPath.row];
ServiceViewController *serviceViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"ServiceView"];
serviceViewController.serviceModel = service;
[self.serviceController pushViewController:serviceViewController animated:YES];
}

Select row of UITableView and push ViewController according to row

I am using a custom control, SWRevealController for left-sliding menu like facebook. I have to ask user to sign in if he is not signed in and selects an option that require sign in.
I show an authentication view controller on clicking and user signs in. On success, I am supposed to push the view controller according to row selected before sign in.
I am using:
[self tableView:self.menuTable didSelectRowAtIndexPath:self.indexPath];
But it does not push the view controller on that row.
I have implemented delegate methods to get response whether user has sign in successfully or not, and I receive success.
Here is my tableView delegate method:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
SWRevealViewController *revealController = [self revealViewController];
UIViewController *frontViewController = revealController.frontViewController;
UINavigationController *frontNavigationController =nil;
self.indexPath = indexPath;
if ( [frontViewController isKindOfClass:[UINavigationController class]] )
frontNavigationController = (id)frontViewController;
NSInteger row = indexPath.row;
if(self.currentUser == nil){
SignInViewController *frontViewController = [[SignInViewController alloc] init];
frontViewController.delegate = self;
frontViewController.title = #"Cashmails";
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:frontViewController];
self.navController = navigationController;
[revealController pushFrontViewController:navigationController animated:YES];
}else{
CashmailViewController *frontViewController = [[CashmailViewController alloc] init];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:frontViewController];
[revealController pushFrontViewController:navigationController animated:YES];
}
}
Here is the delegate method I am using on getting success for sign in:
-(void) userSignInSuccessfully{
[self tableView:self.menuTable didSelectRowAtIndexPath:self.indexPath];
}
I have also tried this:
-(void) userSignInSuccessfully{
SWRevealViewController *revealController = [self revealViewController];
[revealController pushFrontViewController:self.navController animated:NO];
}
How I can achieve this, if I am using wrong approach.

iOS table navcontroller not working

I have a table:
- (void)viewWillAppear:(BOOL)animated
{
self.searchBar.delegate=self;
self.searchResultTable.delegate=self;
self.searchResultTable.dataSource=self;
[self.searchResultTable setHidden:YES];
}
In my cells I insert text and when I click on cell I need go to another table but this not work:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
TableViewController *tvc=[[TableViewController alloc]initWithStyle:UITableViewStyleGrouped];
[self.navigationController pushViewController:tvc animated:YES];
}
Assuming you are doing something like this to present this controller:
SearchViewController *searchViewController = [SearchViewController alloc] init];
[self presentModalViewController:searchViewController animated:YES];
then your view controller doesn't have a navigation controller
You need to change it to
SearchViewController *searchViewController = [SearchViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:searchViewController];
[self presentModalViewController:navController animated:YES];
then [self.navigationController pushViewController:tvc animated:YES]; will work

Resources