In my app, I have a second view controller for another screen. This view controller has a close button that dimisses the view controller. On pressing this close button, the app crashes. It crashes with the following error:
*** Terminating app due to uncaught exception 'UIApplicationInvalidInterfaceOrientation', reason: 'preferredInterfaceOrientationForPresentation must return a supported interface orientation!'
This is the method I use to close the view controller, in the second view controller's .m
- (IBAction)done {
[self dismissViewControllerAnimated:YES completion:nil];
//[self dismissModalViewControllerAnimated:YES];
}
The crash occurs at [self dismissViewControllerAnimated:YES completion:nil];
The second view controller is presented using this method in my main view controller:
-(IBAction)switchViews {
[self presentViewController:secondView animated:YES completion:nil];
//[self presentModalViewController:secondView animated:YES];
}
Code related to rotation in main view controller:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return YES;
}
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAllButUpsideDown;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationMaskPortrait;
}
I haven't been able to resolve this issue. I've looked up that error and tried various solutions, but nothing has worked. Why is this crash happening? What am I doing wrong?
If you need more information, please let me know.
You are returning the wrong thing. The value it expects is UIInterfaceOrientationPortrait, but you're returning UIInterfaceOrientationMaskPortrait. Note the Mask part.
Related
I am trying to call a segue in my iOS app but am getting the error
Could not find a navigation controller for segue ___
I determined that the issue is that when I try to check the current visibleViewController, it is not the ViewController that the segue is linked to:
if(self.navigationController.visibleViewController == self){
[self performSegueWithIdentifier:#"login_success" sender:self];
}else{
NSLog(#"LoginViewController is not currently visible");
}
My question is, how can I set the correct view controller so I can call the segue?
Here is all my code:
LoginViewController: (The first ViewController)
-(IBAction)registerClick:(id)sender{
// open up registration
[self performSegueWithIdentifier:#"registration" sender:self];
}
Registration ViewController (the Modal ViewController)
-(IBAction)finish:(id)sender{
// return back to login view controller
[self dismissViewControllerAnimated:YES completion:nil];
}
LoginViewController segue attempt:
if(self.navigationController.visibleViewController == self){
[self performSegueWithIdentifier:#"login_success" sender:self];
}else{
NSLog(#"LoginViewController is not currently visible");
}
In storyboard I have a button on my Main Menu called showCountdownViewControllerPressed.
This button is supposed to show my XIB called TimerViewController.
But when I run the app, it freezes upon button press and then after a little while crashes the app.
I put this action in my CRViewController.m (my main menu) [I also have imported the TimerViewController.h in this file]
- (IBAction)showCountdownViewControllerPressed:(id)sender {
NSLog(#"showTimerViewController");
TimerViewController *timeController = [[TimerViewController alloc]
initWithNibName:#"TimerViewController" bundle:nil];
[self presentViewController:timeController animated:YES completion:nil];
That's not the answer to your problem but it can help. I'm putting it here because I can't add images on the comments. You can put an exception breakpoint at the bottom of the breakpoints tab, normally it will stop just before the crash and you will get more info about it.
Post where the exception breakpoint it's stopping for getting more help :)
Well, if it is LandScape only, you can add this in TimerViewController for iOS 8, which will make the TimerViewController rotate to the landscape mode.
- (BOOL)shouldAutorotate
{
return YES;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationLandscapeLeft;
}
I have a modally presented view (call it 'current view'). It has an unwind segue to the modally presented view before it. Current view has a button hooked up to the following code:
- (IBAction)inviteUser:(id)sender
{
ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];
picker.peoplePickerDelegate = self;
[self presentViewController:picker animated:NO completion:nil];
}
Current view is set as the delegate to the picker and implements the following delegate methods:
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker
{
// Do nothing
[self dismissViewControllerAnimated:NO completion:nil];
}
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
[self dismissViewControllerAnimated:NO completion:nil];
return NO;
}
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person
property:(ABPropertyID)property
identifier:(ABMultiValueIdentifier)identifier
{
return NO;
}
Nothing crazy so far. When I press the button, my contacts list comes up. I can select a contact and I'm sent back to current view with no crashes and no apparent changes.
Now, current view has another button (back button) hooked up to an unwind segue that I created in the storyboard. I did this by ctrl-dragging from the button to 'Exit' and picking the unwind function I had defined in previous view:
- (IBAction)unwindToThisList:(UIStoryboardSegue*)unwindSegue
{
}
Here's the clincher. If I press the back button while in current view, and I haven't gone into the address book while in this view, it unwinds correctly. No problems. I can go back and forth between those views all day. However, if I have gone into the address book and returned to current view, pressing the back button results in an EXEC_BAD_ACCESS. It makes no difference if I leave the address book by picking a contact or pressing cancel.
I'm completely lost. Pls halp.
I created a test xcode project, having two scenes in navigation,
Pushed the current view (second scene), from first View.
Then implemented the inviteUser method in current view, and I unwinded segue to the first view, after dismissing ABPeoplePickerNavigationController, without an error. Please check there migh be some other error, I guess.
The thing is: I have a modalViewController presented with a button that triggers an IBAction like this:
-(IBAction)myMethod
{
[self dismissModalViewControllerAnimated:YES];
if([delegate respondsToSelector:#selector(presentOtherModalView)])
{
[delegate presentOtherModalView];
}
}
in the root view that is the delegate for that modalViewControllerI've implemented the presentOtherModalView delegate method and it looks like this:
-(void)presentOtherModalView
{
AnotherViewController *viewInstance = [[AnotherViewController alloc]initWithNibName:#"AnotherViewController" bundle:nil];
viewInstance.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:viewInstance animated:YES];
[viewInstance release];
}
The problem is this second modalViewController is not being presented. It gives me the message wait_fences: failed to receive reply: 10004003... How should this be done?
Because they are executed exactly after each other (they don't wait for the view to disappear/appear), it doesn't get executed. Because there can only be one ModalViewController on the screen at a time, you have to first wait for the other ModalViewController to disappear before the next one is put on screen.
You can do this creatively how you want, but the way I did it was something like:
[self dismissModalViewControllerAnimated:YES];
self.isModalViewControllerNeeded = YES;
And then in the underlying ViewController, in the viewDidAppear method, I do this:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (self.isModalViewControllerNeeded) {
[self presentModalViewController:viewInstance animated:YES];
self.isModalViewControllerNeeded = NO;
}
}
Hope it helps!
It is because the dismissModalViewControllerAnimated takes some time to dismiss with animation and you are calling another view to present as modal view before dismissing the 1st modal view so the presenting modal view call was rejected. You should not perform animations when you are not on the view after completely dismissing only you can call another view. To solve this problem call the present modal view after 2 or 3 seconds using time interval or use completion block for dismissModalViewControllerAnimated
You can achieve it by using this
[delegate performSelector:#selector(presentOtherModalView) withObject:nil afterDelay:3];
I am getting the following error whenever I try to switch views like this:
-(void)changeView1ToView4 {
[self.navigationController1 pushViewController:view4 animated:YES];
}
This doesn't happen when the app first loads and user goes directly to this view. This crash only happens when I go to one of my other views, come back to the main menu, and then try to go to this view.
Also if you weren't sure already, I am using a UINavigationController. Also this code is in the app delegate and I am calling it from a view controller which has a parent view so I am using a .reference to call it like this:
[self.reference changeView1ToView4];
Is there any real way to fix this?
Thanks!
Edit1:
[self.navigationController1 pushViewController:view4 animated:NO];
[self.navigationController1 pushViewController:view4 animated:YES];
I tried that and got this crash message in the console:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Pushing the same view controller instance more than once is not supported (<View2: 0x18d540>)'
When pushing 2 views onto the stack, try to call:
[self.navigationController1 pushViewController:view4 animated:YES];
and
[self.navigationController1 pushViewController://secondviewcontrollername// animated:NO];
If you try to push more than one view with the animated: field set to YES on both, then you confuse the stack. Only animate one view at a time.
just an FYI, if you call setViewControllers:animated: there's no need to call pushViewController: afterwards, else you'll get the "Pushing the same view controller instance more than once is not supported" crash.
#try {
[self.navController pushViewController:viewController animated:NO];
} #catch (NSException * e) {
NSLog(#"Exception: %#", e);
[self.navigationController popToViewController:viewController animated:NO];
} #finally {
//NSLog(#"finally");
}
Check this condition before push
if (![[self.navigationController topViewController] isKindOfClass:[YOURCONTROLLER class]])
[self.navigationController pushViewController:YOURCONTROLLER animated:YES];