Problems presenting a second modal view controller - ios

At the moment my error says my view controller is already presenting null. I think i have the right idea with my below code, but I'm not implementing it correctly. Thanks for your help
-(IBAction)datePicker
{
//UIViewController *presenter = self.presentingViewController;
[self dismissViewControllerAnimated:YES completion:^{
/*
UIStoryboard* sb = [UIStoryboard storyboardWithName:#"MainStoryboard.storyboard"
bundle:nil];
UIViewController* dateView = [sb instantiateViewControllerWithIdentifier:#"DatePickerViewController"];
*/
[self performSegueWithIdentifier:#"dueDateSegue" sender:self];
//[presenter presentViewController:dateView animated:YES completion:nil];
/*
[self presentViewController:dateView animated:YES completion:^{
UIBarButtonItem *saveDate = [[UIBarButtonItem alloc]
initWithTitle:#"Save Date"
style:UIBarButtonItemStyleDone
target:self
action:#selector(labelDatePicker)];
self.navigationItem.rightBarButtonItem = saveDate;
pick = [[UIDatePicker alloc] init];
[pick setFrame:CGRectMake(0,200,320,120)];
//[pick addTarget:self action:#selector(done) forControlEvents:UIControlEventValueChanged];
//dateFieldText.delegate = self;
//dateFieldText.inputView = pick;
}];
*/
}];
}

In the method datePicker add the following line as the first line of code:
UIViewController *presenter = self.presentingViewController;
And then instead of :
[self presentViewController:dateView animated:YES completion:nil];
try using:
[presenter presentViewController:dateView animated:YES completion:nil];

Related

Black screen after button click

I'm quite new to Objective-C. I want to go to another view controller but it shows me only the black screen after the button click. Is there something that I'm missing here?
Here is my code:
- (IBAction)measuring1stscan:(id)sender {
measuringscan *second = [[measuringscan alloc]initWithNibName:nil bundle:nil];
[self presentViewController:second animated:NO completion:NULL];
}
*measuringscan is the name for another view controller
viewConreoller default is no color, it is black. just add second.view.backgroundColor = [UIColor redColor];
- (IBAction)measuring1stscan:(id)sender {
measuringscan *second = [[measuringscan alloc] init];
second.view.backgroundColor = [UIColor redColor];
[self presentViewController:second animated:NO completion:NULL];
}
#rose is right try to give different color and then check.
Still you face same issue then try to run below code.
Embadded viewcontroller into navigation controller and give unique identifier to second viewcontroller.
- (IBAction)measuring1stscan:(id)sender
{
UIStoryboard *st = [UIStoryboard storyboardWithName:[NSString stringWithFormat:#"StoryboardWithName"] bundle:NULL];
measuringscan *second = [st instantiateViewControllerWithIdentifier:#"viewcontrollerIdentifier"];
[self.navigationController pushViewController:second animated:YES];
}
If you are using storyboard then use following
measuringscan *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"StoryboardIdentifier"];
[self presentViewController:controller animated:YES completion:nil];
or
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:[NSString stringWithFormat:#"StoryboardName"] bundle:nil];
measuringscan *controller = [storyboard instantiateViewControllerWithIdentifier:#"viewcontroller'sIdentifier"];
[self presentViewController:controller animated:YES completion:nil];
And if you aren't using storyboard instead you are using xib's then use following
measuringscan *controller = [[measuringscan alloc] initWithNibName:nil bundle:nil];
[self presentViewController:controller animated:YES completion:nil];
Points to remember (as said by #rmaddy)
Class name should be start with capital letter
Variable name should start with small letter
It is the naming convention that should be followed by a developer.
For more details click here

Fix Warning: Attempt to present ViewController on NavigationController whose view is not in the window hierarchy

Currently, I have set up a log-in view for users of my app. Below is the code that presents this log-in view to the user:
// Handle how we present the view
if (self.notificationToProcess != nil) {
[self.navigationController dismissViewControllerAnimated:YES completion:^{
SWNotificationsViewController *viewController = [[NotificationsViewController alloc] init];
viewController.initialDataID = self.notificationToProcess[#"Data"];
self.notificationToProcess = nil;
[self.navigationController pushViewController:viewController animated:YES];
}];
} else if (self.detailURL != nil) {
[self.navigationController dismissViewControllerAnimated:YES completion:^{
WebViewController *wvc = [[WebViewController alloc] init];
wvc.URL = self.detailURL;
wvc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self.navigationController presentViewController:wvc animated:YES completion:nil];
self.detailURL = nil;
}];
} else {
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
What I'm attempting to do now is display a web-view first if the user has just updated the app. Below is what this new code looks like:
// Handle how we present the view.
if (self.notificationToProcess != nil) {
[self.navigationController dismissViewControllerAnimated:YES completion:^{
SWNotificationsViewController *viewController = [[SWNotificationsViewController alloc] init];
viewController.initialDataID = self.notificationToProcess[#"Data"];
self.notificationToProcess = nil;
[self.navigationController pushViewController:viewController animated:YES];
}];
} else if (self.detailURL != nil) {
[self.navigationController dismissViewControllerAnimated:YES completion:^{
SWWebViewController *wvc = [[SWWebViewController alloc] init];
wvc.URL = self.detailURL;
wvc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self.navigationController presentViewController:wvc animated:YES completion:nil];
self.detailURL = nil;
}];
else if (![versionOfLastRun isEqual:currentVersion])
{
SWWebViewController *webViewController = [[SWWebViewController alloc] init];
NSString *url=#"http://someurl";
webViewController.URL = url;
webViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self.navigationController presentViewController:webViewController animated:YES completion:nil];
[[NSUserDefaults standardUserDefaults] setObject:currentVersion forKey:#"VersionOfLastRun"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
else if (versionOfLastRun == nil){
// First start after installing the app
}
else {
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}
However, when I run the app, the web view is not displayed, I get a warning of:
Warning: Attempt to present ViewController on NavigationController whose view is not in the window hierarchy!
Can anyone help me diagnose the problem? Thank you!
Seems like your viewController is not in Navigation controller hierarchy. This means that your controller is not connected with navigation controller stack which should handle presented controllers.
The other thing that should help is setting your root view controller as follows:
self.window.rootViewController = self.ViewController;
EDIT: since you mention that you don't use storyboards, setting rootViewController should do the trick.
Try to set the window's rootViewController to the navigation controller after you initialize the navigation controller:
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:mainController];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = navController;
This is how I'm doing it without storyboards.
The problem was that I didn't call self.navigationController dismissViewControllerAnimated:YES completion:^
After correcting this (see listing below), my WebView was shown as expected.
else if (![versionOfLastRun isEqual:currentVersion])
{
[self.navigationController dismissViewControllerAnimated:YES completion:^{
SWWebViewController *webViewController = [[SWWebViewController alloc] init];
NSLog(#"%#", self.window.rootViewController);
NSString *url=#"http://devstatwatch.drbsystems.com/releases_mobile.php";
webViewController.URL = url;
webViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self.navigationController presentViewController:webViewController animated:YES completion:nil];
[[NSUserDefaults standardUserDefaults] setObject:currentVersion forKey:#"VersionOfLastRun"];
[[NSUserDefaults standardUserDefaults] synchronize];
}];
}

modalPresentationStyle from button click

I have a _exampleButton:
_exampleButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_exampleButton setBackgroundColor:[UIColor redColor]];
[_exampleButton addTarget:self action:#selector(certificatesButtonTouched) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_exampleButton];
and the action:
-(void)certificatesButtonTouched
{
if(!_certificatesWindow)
{
_certificatesWindow = [[AWCertificatesViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc]
initWithRootViewController:_certificatesWindow];
navController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:navController animated:YES completion:nil];
[_certificatesWindow release];
}
else {
[_certificatesWindow.view removeFromSuperview];
[_certificatesWindow release];
_certificatesWindow = nil;
}
}
this presents the window in modal view controller from other class:
- (void)viewDidLoad
{
[super viewDidLoad];
UIBarButtonItem *cancelItem = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
target:self
action:#selector(cancel:)];
self.navigationItem.leftBarButtonItem = cancelItem;
UITableView *table = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStylePlain];
[self.view addSubview:table];
_tableFromButton = table;
}
- (void)cancel:(id)sender
{
[self.presentingViewController dismissViewControllerAnimated:YES
completion:nil];
}
but after clicking the Cancel button, the Modal view controller view disappears, but if I click the _exampleButton again once- it will not appear, so I have to click it twice to show the modal view controller again. What is the problem?
It does this because that is what your code tell it to do...
You dismiss the view controller in -(void)cancel:(id)sender but this will not result in the _certificatesWindow iVar becoming nil in your first view controller. So when you touch the exampleButton again it will execute the else clause and clean up the _certificatesWindow view controller.
You should either use delegation or a code block to have the first view controller dismiss the second or remove the if/else test from your certificatesButtonTouched. Another alternative is to modify this method so that if _certificatesWindow is not nil it is reused -
-(void)certificatesButtonTouched
{
if(!_certificatesWindow)
{
_certificatesWindow = [[AWCertificatesViewController alloc] init];
}
UINavigationController *navController = [[UINavigationController alloc]
initWithRootViewController:_certificatesWindow];
navController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:navController animated:YES completion:nil];
}
But this may or may not be desirable depending on what the second view controller shows.
I would also suggest you look at converting to ARC if possible
The problem is after you tap "Cancel", _certificatesWindow still exists when you tap on certificatesButtonTouched. It will go to the Else statement on the First tap to make _certificatesWindow = nil.
if _certificatesWindow is not needed when you tap cancel, you might want to do the following:-
- (void)cancel:(id)sender
{
[self.presentingViewController dismissViewControllerAnimated:YES
completion:nil];
[_certificatesWindow.view removeFromSuperview];
[_certificatesWindow release];
_certificatesWindow = nil;
}
allocate view like this in view did load method
if(!_certificatesWindow)
{
_certificatesWindow = [[ViewController1 alloc] init];
}
-(void)certificatesButtonTouched
{
UINavigationController *navController = [[UINavigationController alloc]
initWithRootViewController:_certificatesWindow];
navController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:navController animated:YES completion:nil];
}
replace your code with this
-(void)certificatesButtonTouched
{
if(!_certificatesWindow)
{
_certificatesWindow = [[AWCertificatesViewController alloc] init];
}
UINavigationController *navController = [[UINavigationController alloc]
initWithRootViewController:_certificatesWindow];
navController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:navController animated:YES completion:nil];
[_certificatesWindow release];
}

GKGameCenterViewController wont dismiss?

I dont get it please help i DONT get a log when i hit done
- (IBAction)loadScores:(id)sender {
GKGameCenterViewController* gameCenterController = [[GKGameCenterViewController alloc] init];
gameCenterController.viewState = GKGameCenterViewControllerStateLeaderboards;
// gameCenterController.gameCenterDelegate = self;
[self presentViewController:gameCenterController animated:YES completion:nil];
}
-(void)gameCenterViewControllerDidFinish:(GKGameCenterViewController*)gameCenterViewController {
NSLog(#"rfffff");
[self dismissViewControllerAnimated:YES completion:nil];
UIViewController *vc = self.view.window.rootViewController;
[vc dismissViewControllerAnimated:YES completion:nil];
}
You have commented the delegates of the GKGameCenterViewController. This means all the delegate methods will not be called like the one that dismisses the view controller. So I suggest you uncomment this line and then run the code and see.

EKEventview controller not showing navigation bar

I used the following code to view the event. But navigation bar doesn't visible.
EKEventViewController *addController = [[EKEventViewController alloc] initWithNibName:nil bundle:nil];
addController.event = self.event;
addController.allowsEditing = YES;
addController.allowsCalendarPreview = YES;
[self.navigationController presentViewController:addController animated:YES completion:nil];
with Present viewcontroller you need to Add sepreated NavigationController for UIViewcontroller like:-
EKEventViewController *addController = [[EKEventViewController alloc] initWithNibName:#"EKEventViewController" bundle:nil];
UINavigationController *navController=[[UINavigationController alloc]initWithRootViewController:addController];
addController.event = self.event;
addController.allowsEditing = YES;
addController.allowsCalendarPreview = YES;
if ([self respondsToSelector:#selector(presentViewController:animated:completion:)])
{
[self presentViewController:navController animated:YES completion:nil];
}
else
{
[self presentModalViewController:navController animated:YES];
}

Resources