getting view controller nil when doing presentViewController - iphone

Each row clicked will lead you to another view controller
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if( indexPath.row == 0 ){
titleController = [[TitleFundraiserController alloc] initWithNibName:#"TitleFundraiserController" bundle:nil];
[self.navigationController presentViewController:titleController animated:YES completion:nil];
}
if( indexPath.row == 1 ) {
recipientController = [[RecipientController alloc] initWithNibName:#"RecipientController" bundle:nil];
[self.navigationController presentViewController:recipientController animated:YES completion:nil];
}
if( indexPath.row == 2 ) {
fundController = [[FundingController alloc] initWithNibName:#"FundingController" bundle:nil];
[self.navigationController presentViewController:recipientController animated:YES completion:nil];
}
if( indexPath.row == 3 ) {
locationController = [[LocationController alloc] initWithNibName:#"LocationController" bundle:nil];
[self.navigationController presentViewController:locationController animated:YES completion:nil];
}
}
However, sometimes I am getting this error from the console and my program is crashing
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:
'Application tried to present a nil modal view controller on target <UINavigationController: 0x7c7a340>.'
I dont know why it is saying so .
Please help if you have experienced this issue before.
Thanks

You are presenting recipientController in your if (indexPath.row == 2) statement when you should be presentingfundController
Here is the corrected code:
if( indexPath.row == 2 ) {
fundController = [[FundingController alloc] initWithNibName:#"FundingController" bundle:nil];
[self.navigationController presentViewController:fundController animated:YES completion:nil];
}
You are getting that error, because recipientController would be nil when presenting here

The only thing I see wrong with your code is that after presentViewController, you need to release the variable as well:
if ( indexPath.row == 0 ) {
titleController = [[TitleFundraiserController alloc] initWithNibName:#"TitleFundraiserController" bundle:nil];
[self.navigationController presentViewController:titleController animated:YES completion:nil];
[titleController release];
}
I don't see any reason for the error you are getting being random, isn't it always in the same row?. What is happening is the ViewController is not being loaded from the nib and therefore returning nil.

Related

iOS6 autorotation - UIPageViewController

My UI structure:
UINavigationController
--UIViewController(first)
|
|Modal
|
V
UINavigationController (subclass)
--UIViewController (contains UIPageViewController)
For iOS6 new autorotation, I created a subclass of UINavigationController and added:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return UIInterfaceOrientationIsPortrait(interfaceOrientation);
}
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
Only want keep the orientation is portrait.
And I initialize UIPageViewController like:
self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
PageDataViewController *startingViewController = [self viewControllerAtIndex:start storyboard:self.storyboard];
NSArray *viewControllers = [NSArray arrayWithObject:startingViewController];
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:NULL];
self.pageViewController.dataSource = self;
[self addChildViewController:self.pageViewController];
[self.view addSubview:self.pageViewController.view];
// Set the page view controller's bounds using an inset rect so that self's view is visible around the edges of the pages.
CGRect pageViewRect = self.view.bounds;
self.pageViewController.view.frame = pageViewRect;
[self.pageViewController didMoveToParentViewController:self];
Then I perform the Modal segue,
if the first UIViewController is portrait, the pageViewController works,
but if the first UIViewController is landscape, I always got exception:
* Assertion failure in -[UIPageViewController willAnimateRotationToInterfaceOrientation:duration:],
/SourceCache/UIKit_Sim/UIKit-2372/UIPageViewController.m:945
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'No view controllers'
** First throw call stack: (0x2a5e012 0x19bae7e 0x2a5de78 0x1450f35 0xd75974 0x9f12b4 0x9f13ea 0x9e4c32 0x9f1372 0x9f13ea 0x9e4c32
0x9f1372 0x9f1751 0x93a1a6 0xbee5f9 0x9ec4f3 0x9ec777 0x9ec7b7
0xd57fe2 0xd49ad9 0xd49b54 0x9b1899 0x9b1b3d 0x13b8e83 0x2a1d376
0x2a1ce06 0x2a04a82 0x2a03f44 0x2a03e1b 0x2c967e3 0x2c96668 0x90265c
0xea7d 0x2685 0x1) libc++abi.dylib: terminate called throwing an
exception
Actually There is another solution for it.
The rotation just calling the willAnimateRotationToInterfaceOrientation method to the rootViewController, you have to implement the method of it.
#interface UIPageViewController (Rotation)
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;
#end
//Implementation file
#import "UIPageViewController+Rotation.h"
#implementation UIPageViewController(Rotation)
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {}
#end
In the documentation about "supportedInterfaceOrientations" it is written:
When the user changes the device orientation, the system calls this method on the root view controller or the topmost presented view controller that fills the window
Did you try setting the rootViewController for the main windows to your current NavigationController classes?
Like in the AppDelegate:
self.window.rootViewController = nvc;
And when your navigationController is changing, set the rootViewController again...
I have "fixed" the problem, by setting view controllers to UIPageViewController in viewWillAppear: again, because when this method is called, spine location for page view controller is correct and based on this information i set one, or two pages (view controllers)
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if(self.pageViewController.spineLocation == UIPageViewControllerSpineLocationMid)
{
BookPageViewController *currentViewController = self.pageViewController.viewControllers[0];
NSArray *viewControllers = nil;
NSUInteger indexOfCurrentViewController = [self.modelController indexOfViewController:currentViewController];
if (indexOfCurrentViewController == 0 || indexOfCurrentViewController % 2 == 0) {
UIViewController *nextViewController = [self.modelController pageViewController:self.pageViewController viewControllerAfterViewController:currentViewController];
viewControllers = #[currentViewController, nextViewController];
} else {
UIViewController *previousViewController = [self.modelController pageViewController:self.pageViewController viewControllerBeforeViewController:currentViewController];
viewControllers = #[previousViewController, currentViewController];
}
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward | UIPageViewControllerNavigationDirectionReverse animated:NO completion:nil];
}
if(self.pageViewController.spineLocation == UIPageViewControllerSpineLocationMin)
{
[self.pageViewController setViewControllers:[NSArray arrayWithObject:[self.pageViewController.viewControllers objectAtIndex:0]] direction:UIPageViewControllerNavigationDirectionForward | UIPageViewControllerNavigationDirectionReverse animated:NO completion:nil];
}
}
and set UIPageViewController Delegate method as below
- (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation
{
BookPageViewController *currentViewController = self.pageViewController.viewControllers[0];
if(UIInterfaceOrientationIsPortrait(orientation))
{
[self.pageViewController setViewControllers:[NSArray arrayWithObject:currentViewController] direction:UIPageViewControllerNavigationDirectionForward | UIPageViewControllerNavigationDirectionReverse animated:NO completion:nil];
pageViewController.doubleSided = NO;
return UIPageViewControllerSpineLocationMin;
}
if(UIInterfaceOrientationIsLandscape(orientation))
{
NSArray *viewControllers = nil;
NSUInteger indexOfCurrentViewController = [self.modelController indexOfViewController:currentViewController];
if (indexOfCurrentViewController == 0 || indexOfCurrentViewController % 2 == 0) {
UIViewController *nextViewController = [self.modelController pageViewController:self.pageViewController viewControllerAfterViewController:currentViewController];
viewControllers = #[currentViewController, nextViewController];
} else {
UIViewController *previousViewController = [self.modelController pageViewController:self.pageViewController viewControllerBeforeViewController:currentViewController];
viewControllers = #[previousViewController, currentViewController];
}
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward | UIPageViewControllerNavigationDirectionReverse animated:NO completion:nil];
return UIPageViewControllerSpineLocationMid;
}
return UIPageViewControllerSpineLocationMin;
}
I have "fixed" the problem, by setting view controllers to UIPageViewController in viewWillAppear: again, because when this method is called, spine location for page view controller is correct and based on this information i set one, or two pages (view controllers)

UIAlertView button to another ViewController

I have two buttons for my UIAlertView. One of them goes back to TableViewController while another one have to go to another ViewController. The button that goes to the TableViewController can work. But the button that goes to the ViewController is showing me a blank view when I click the button.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
QuizTableViewController *quizTable = [self.storyboard instantiateViewControllerWithIdentifier:#"quizTable"];
UINavigationController *quizController = [[UINavigationController alloc] initWithRootViewController:quizTable];
[quizController setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
[self presentViewController:quizController animated:YES completion:nil];
}
if (buttonIndex == 1)
{
QuizAnsViewController *quizAns = [[QuizAnsViewController alloc] initWithNibName:nil bundle:nil];
[self presentViewController:quizAns animated:YES completion:nil];
}
}
The second part of the code is for the button to go another ViewController.
Anybody can help please? Thank you.
It seems you are using Story board so this might work
if (buttonIndex == 1){
QuizAnsViewController *quizAns = [self.storyboard instantiateViewControllerWithIdentifier:#"Identifier_of_that_view_controller"];
[self presentViewController:quizAns animated:YES completion:nil];
}
you use NavigationController than I think this code is Solve your problem. You can Try.
if (buttonIndex == 1)
{
QuizAnsViewController * quizAns = [[[QuizAnsViewController alloc] initWithNibName:#"QuizAnsViewController" bundle:nil] autorelease];
[self.navigationController quizAns animated:YES];
}

how can i push a view only once with in a method calling multiple times in iphone

- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message
{
ChatViewController *chatView;
if(contactView==nil)
{
chatView=[[ChatViewController alloc] initWithNibName:#"ChatViewController" bundle:nil];
}
[self.navigationController pushViewController:chatView animated:YES];
[messageDelegate newMessageReceived:m];
}
The above delegate method called for every incoming message.When it called, it goes to a new UIViewController.Here my problem is a view pushed multiple tinmes,so error will be occered.how can i fix this error in iphone
Add this snippet before pushing the view controller
BOOL viewControllerAlreadyPushed = NO;
for (UIViewController *controller in self.navigationController.viewControllers) {
if ([controller isKindOfClass:[ChatViewController class]]) {
viewControllerAlreadyPushed = YES;
}
}
if(!viewControllerAlreadyPushed) //if not pushed, push it
{
ChatViewController *chatView;
if(contactView==nil)
{
chatView=[[ChatViewController alloc] initWithNibName:#"ChatViewController" bundle:nil];
}
[self.navigationController pushViewController:chatView animated:YES];
[messageDelegate newMessageReceived:m];
}

Push to another view with UIBarButtonSystemItemAdd

I am trying to edit the add button to push to another view.
But I am receiving an error
-(void)locationAdd:(id)sender{
if([self.parentViewController isKindOfClass:[UINavigationController class]]){
UINavigationController *parent = (UINavigationController *)self.parentViewController;
if ([[parent viewControllers] objectAtIndex:0] == self) {
LocationsAddViewController *alocationAddViewController = [[[LocationsAddViewController alloc] initWithNibName:#"LocationAddView" bundle:[NSBundle mainBundle]] autorelease];
//self.locationAddViewController = alocationAddViewController;
alocationAddViewController.title = #"Toevoegen";
[self.parentViewController pushViewController:alocationAddViewController animated:YES];
}
else if([[parent viewControllers] objectAtIndex:2] == self){
LocationsAddViewController *alocationAddViewController = [[[LocationsAddViewController alloc] initWithNibName:#"LocationAddView" bundle:[NSBundle mainBundle]] autorelease];
alocationAddViewController.title = #"Toevoegen";
[self.parentViewController pushViewController:alocationAddViewController animated:YES];
}
}
}
Because the view can be reached from 2 other views and it has to look different, I have used
if([self.parentViewController isKindOfClass:[UINavigationController class]]){
UINavigationController *parent = (UINavigationController *)self.parentViewController;
if ([[parent viewControllers] objectAtIndex:0] == self) {
to check where it comes from.
The problem is at:
[self.parentViewController pushViewController:alocationAddViewController animated:YES];
I am receiving the error:
+[LocationsTableViewController pushViewController:animated:]: unrecognized selector sent to class 0x23510
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[LocationsTableViewController pushViewController:animated:]: unrecognized selector sent to class 0x23510'
Can someone help me?
What did I do wrong?
Your error indicates that you're trying to call pushViewController:animated: on your LocationsTableViewController class object. This shouldn't be possible given the code you posted. Are you sure you pasted in the exact code that threw the exception? (It's suspicious that your if and else if blocks do the exact same thing.)

NSInvalidArgumentException

I Am creating an iPhone application which displays an UITableView at the start with some text in the cells. When a user taps a cell it should transition to another view. When I run the application in the iPhone Simulator and click on a cell I get the following error:
2009-09-23 12:20:03.554 ZDFMobiel[751:20b] *** Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '*** -[RootViewController eigenRisicoView]:
unrecognized selector sent to instance 0xd1d1a0'
2009-09-23 12:20:03.555 ZDFMobiel[751:20b] Stack: (
Here is the function (In RootViewController.m) where the error occurred. It happens at the
if(self.eigenRisicoView == nil) {
line or the at the other if statements, depending on which cell you click.
// Override to support row selection in the table view.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
ZDFMobielAppDelegate *appDelegate = (ZDFMobielAppDelegate *)[[UIApplication sharedApplication] delegate];
NSString *content = (NSString *)[appDelegate.menuItems objectAtIndex:indexPath.row];
switch (indexPath.row) {
case 0:
if(self.eigenRisicoView == nil) {
EigenRisicoViewController *viewController = [[EigenRisicoViewController alloc] initWithNibName:#"EigenRisicoViewController" bundle:[NSBundle mainBundle]];
self.eigenRisicoView = viewController;
[viewController release];
}
[self.navigationController pushViewController:self.eigenRisicoView animated:YES];
self.eigenRisicoView.title = content;
break;
case 1:
if(self.declaratieStatusView == nil) {
DeclaratieStatusViewController *viewController = [[DeclaratieStatusViewController alloc] initWithNibName:#"DeclaratieStatusViewController" bundle:[NSBundle mainBundle]];
self.declaratieStatusView = viewController;
[viewController release];
}
[self.navigationController pushViewController:self.declaratieStatusView animated:YES];
self.declaratieStatusView.title = content;
break;
case 2:
if(self.vergoedingenView == nil) {
VergoedingenViewController *viewController = [[VergoedingenViewController alloc] initWithNibName:#"VergoedingenViewController" bundle:[NSBundle mainBundle]];
self.vergoedingenView = viewController;
[viewController release];
}
[self.navigationController pushViewController:self.vergoedingenView animated:YES];
self.vergoedingenView.title = content;
break;
case 3:
if(self.zoekenZorgInstView == nil) {
ZoekenZorgInstViewController *viewController = [[ZoekenZorgInstViewController alloc] initWithNibName:#"ZoekenZorgInstViewController" bundle:[NSBundle mainBundle]];
self.zoekenZorgInstView = viewController;
[viewController release];
}
[self.navigationController pushViewController:self.zoekenZorgInstView animated:YES];
self.zoekenZorgInstView.title = content;
break;
default:
break;
}
// Navigation logic may go here -- for example, create and push another view controller.
// AnotherViewController *anotherViewController = [[AnotherViewController alloc] initWithNibName:#"AnotherView" bundle:nil];
// [self.navigationController pushViewController:anotherViewController animated:YES];
// [anotherViewController release];
}
This is my RootControllerView.h file
#import "EigenRisicoViewController.h";
#import "DeclaratieStatusViewController.h";
#import "VergoedingenViewController.h";
#import "ZoekenZorgInstViewController.h";
#import "ZDFMobielAppDelegate.h";
#interface RootViewController : UITableViewController {
EigenRisicoViewController *eigenRisicoView;
DeclaratieStatusViewController *declaratieStatusView;
VergoedingenViewController *vergoedingenView;
ZoekenZorgInstViewController *zoekenZorgInstView;
}
#property(nonatomic,retain) EigenRisicoViewController *eigenRisicoView;
#property(nonatomic,retain) DeclaratieStatusViewController *declaratieStatusView;
#property(nonatomic,retain) VergoedingenViewController *vergoedingenView;
#property(nonatomic,retain) ZoekenZorgInstViewController *zoekenZorgInstView;
#end
I Am new to iPhone development, Objective C and XCode so I don't understand what the error means..
Does anyone know what I am doing wrong?
I'd need to see the whole implementation, but it sounds like you didnt #synthesize eigenRisicoView;