iPad Orientation change returns SIGABRT signal - ios

I am making an app wherein when I load the app and change the orientation, it is able to handle the orientation. But if I tap on any TableViewCell in RootViewController to display a table in DetailViewController for a splitViewBased app and then change the orientation then my app crashes with SIGABRT and gives the following message :
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_UITableViewReorderingSupport count]: unrecognized selector sent to instance 0x4e4eb30'
The method that I am writing to handle orientation is :
// Ensure that the view controller supports rotation and that the split view can therefore show in both portrait and landscape.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
//hot fix sometimes in multilevel bar button is shown in landscape mode.
if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
[[self navigationItem] setLeftBarButtonItem:nil];
}
else {
[[self navigationItem] setLeftBarButtonItem:self.appDelegate.rootPopoverButtonItem];
}
return YES;
}

You would most probably be using an array to load the contents to the table, and at the point of reloading or filling the table with contents, the array count might be 0 or the array instance would have lost its scope, and you would be trying to access it directly from cellForRowAtIndexPath delegate. If it is so, then try retaining the array, or allocating it.

Add NSLog after the if and else to make sure it's reading each one and see if where the crash is. If there's the didRotateTo or didRotateFrom, add NSLog there too to see what's going on.
Also try just return YES: in the shouldAutorotate and nix the if/else to make sure it does rotate properly and there's nothing else getting in the way.
Lastly, check your Target > Supported Device Orientation to make sure all orientations are supported

Related

Pushing A View Controller Crashes The App

Here's the scenario: I am using MWPhotoBrowser. I can push it fine once. The second time I try to push it the app crashes with nothing helpful. This is an ARC project, and this exact same code works fine in previous versions of the app. I am dumbfounded.
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
selectedIndexPath = indexPath;
if(browser == nil)
{
browser = [[MWPhotoBrowser alloc] initWithDelegate:self];
}
// Set options
browser.displayActionButton = YES; // Show action button to allow sharing, copying, etc (defaults to YES)
browser.displayNavArrows = YES; // Whether to display left and right nav arrows on toolbar (defaults to NO)
browser.zoomPhotosToFill = NO; // Images that almost fill the screen will be initially zoomed to fill (defaults to YES)
[browser setCurrentPhotoIndex:indexPath.row]; // Example: allows second image to be presented first
//browser.wantsFullScreenLayout = YES; // iOS 5 & 6 only: Decide if you want the photo browser full screen, i.e. whether the status bar is affected (defaults to YES)
// Present
[self.navigationController pushViewController:browser animated:YES];
}
Tap a cell once, MWPhotoBrowser opens fine. Go back, tap a cell again, the app crashes just with the debugger but no call stack or error reason:
(lldb):
browser is a strong member variable. It isn't being deallocated prematurely. I can also guarantee it is crashing exactly on the last line of the method.
Can someone please enlighten me on this? I'd solve it if the app at least gave me a reason for the crash and not just throw the debugger on my face.
I have used MWPhotoBrowser extensively and ran across the same problem once. The way I solved it was by checking the MWPhoto objects to see if they actually had been set properly. I realised that I had not created some of them, hence the crash. I would check the place where you store your MWPhotos and make sure they are all set. Hope this helps!

"Array out of bounds" error when trying to add subview in iOS

I'm currently writing an app and I'm experiencing a problem that seems to be caused by code that I did not write (i.e., Apple's classes). I create an instance of a subclass of UIViewController that I wrote. I add it as a child view controller of another custom view controller. Then, when I try to add this new view controller's view as a subview of the parent view controller's view I get a crash with this error.
Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'
I have tested and determined that the problem is specifically cause by trying to add the view as a subview. I reference the view in an NSLog just to make sure that it isn't simply the act of referencing it that's causing the error. I've tried adding the view as a subview of different views and that also crashed, so the problem is not with the parent view. Finally, I have tried to add a different view as a subview to the parent view and that did work, further proving that the parent view is fine, and that the prospective subview is at fault. The code where I allocate it is this:
ScheduleSelectorViewController* selector = [[ScheduleSelectorViewController alloc] initWithNibName:#"ScheduleSelectorViewController" bundle:nil];
This has always worked for me. I don't know what it is I've changed. I don't know enough about the inner workings of subview hierarchy to know which array is empty and is causing this crash, so if anyone can help me out I would be extremely grateful.
If there's any other information I could supply that would help let me know.
UPDATE:
Here is the code where it crashes. I have placed NSLogs to indicate the line at which it breaks.
- (void) addViewControllerToStack:(UIViewController *)controller withKey:(NSString *)key
{
if ( !self.stack ) {
self.stack = [[NSMutableDictionary alloc] init];
}
NSLog(#"subviews %#", [controller.view subviews]);
[[controller view] setFrame:offScreenFrame];
[self addChildViewController:controller];
NSLog(#"code gets to here");
[self.view addSubview:controller.view];
NSLog(#"but not to here");
[self.view bringSubviewToFront:controller.view];
[self.stack setObject:controller forKey:key];
[self.stackKeys addObject:key];
}
For the record, the subviews array is not nil.
Check if you have set view's.hidden = YES; somewhere
I was pulling my hair for more than hour to find out I was hiding my pager control and try to set the pageIndicatorTintColor property later which also throw array out of bounds issue.
Make sure you did not override init/ initWithNibName methods in ScheduleSelectorViewController without calling the super methods.
And of course you can always print out [self.view subviews] for parent view in console to understand if subview array is whether nil. If it is nil you should initiate it before adding any views.

[CustomViewController respondsToSelector:]: message sent to deallocated instance

This is used to work fine for my pre-ARC code, but since refactoring all the project to be ARC compatible, I start getting this crash:
[CustomViewController respondsToSelector:]: message sent to deallocated instance
My project is an iPad app with a split view, but contrary to apple documentation, previous developer has put another view controller to be visible on app launch before split view. So I know this is not the right way to do, but as I said it used to work before ARC integration so I need to get a workaround with this.
The root view controller which contain a menu of items, each item display a detail form to be filled, then a click on next button move to the next detail screen, etc.
The issue starts when I click on home button put on root view to get back to the home view, here is the relevant code that move the user to the home screen:
//this method is in the appdelegate, and it gets called when clikc on home button located on the root view
- (void) showHome
{
homeController.delegate = self;
self.window.rootViewController = homeController;
[self.window makeKeyAndVisible];
}
Then when I click on a button to get back to the split view (where are the root/details view), the app crashes with the above description. I profiled the app with instruments and the line of code responsible of that is located in the RootViewController, in the didSelectRowAtIndexPath method, here is the relevant code:
if(indexPath.row == MenuCustomViewController){
self.customVC=[[CustomViewController alloc] initWithNibName:#"CustomVC"
bundle:nil];
[viewControllerArray addObject:self.customVC];
self.appDelegate.splitViewController.delegate = self.customVC;
}
customVC is a strong property, I tried to allocate directly and assign to the instance variable but that didn't help to fix the crash. Any thoughts ?
EDIT:
Here is the stack trace given by instruments:
[self.appDelegate.splitViewController setViewControllers:viewControllerArray];//this line caused the crash
[viewControllerArray addObject:self.appDescVC];//this statement is called before the above one
self.custinfoVC=[[CustInfoViewController alloc] initWithNibName:#"CustInfo" bundle:nil];//this statement is called before the above one
self.appDelegate.splitViewController.delegate = self.appDescVC;//this statement is called before the above one
custinfoVC and appDescVC are strong properties.
I solved this problem by setting my delegates and datasources to nil in the dealloc method. Not sure if it'll help you but its worth a try.
- (void)dealloc
{
homeController.delegate = nil;
//if you have any table views these would also need to be set to nil
self.tableView.delegate = nil;
self.tableView.dataSource = nil;
}
You may want to setup the CustomViewController during app launch, and display the other views modally on top if necessary. The error message you're getting is because something is getting released by ARC prematurely. It might have not manifested before because pre-arc stuff wasn't always deallocated immediately. ARC is pretty serious about releasing stuff when it leaves scope
Hard to tell without seeing a lot more of the code involved, and what line it breaks on, etc.
This:
- (void) showHome {
//THIS: where is homeController allocated?
homeController.delegate = self;
self.window.rootViewController = homeController;
[self.window makeKeyAndVisible];
}
EDIT:
Add this line right above the line that causes your crash
for (id object in viewControllerArray) {
NSLog(#"Object: %#",object);
}
I had the same Problem.If you are not using "dealloc" method then use "viewWillDisappear" to set nil.
It was difficult to find which delegate cause issue, because it does not indicate any line or code statement for my App So I have try some way to identify delegate, Maybe it becomes helpful to you.
1.Open xib file and from file's owner, Select "show the connections inspector" right hand side menu. Delegates are listed, set them to nil which are suspected.
(Same as my case)Property Object like Textfield can create issue, So set its delegate to nil.
-(void) viewWillDisappear:(BOOL) animated{
[super viewWillDisappear:animated];
if ([self isMovingFromParentViewController]){
self.countryTextField.delegate = nil;
self.stateTextField.delegate = nil;
}
}

How to remove all the UIPopOver references of my app on idle time exceed

Im setting an MaxIdleTime in my app once if no userInteraction happened within this specified time i'm just removing the existing view from my window and adding my login (Home) view as subview to my apps UIWindow through a method called logout.
In this logout i'm just removing all the references which are alive but if any of the UIPopOverController is visible on any view during this logout call i'm getting exception
-[UIPopoverController dealloc] reached while popover is still visible.
Im making popover instance to nil in viewDidUnload even though i'm getting this exception and app is crashing and my project is ARC enabled.
How to overcome this exception, any help is appreciated in advance.
To remove all the subviews in your main view when the timer fires, use the following code:
for (UIView *sub in [[_view subviews] copy]) {
[sub removeFromSuperView];
sub = nil;
}
As for the popovers, simply remove the one currently onscreen with:
[pop dismissPopoverAnimated:NO];
pop = nil;

Choosing From Library using UIImagePickerControllerSourceTypeSavedPhotosAlbum

I would like to have choosing images or videos as one option when taking photos or videos. When i seem to click the option, the app crashes. I am using ios 6 and it seems that apple has included some privacy issues when the app tries to search for existing images and videos. Besides that, should i still be using UIImagePickerControllerSourceTypeSavedPhotosAlbum or use something else?
Part of my code:
if (buttonIndex == 2) {
imgpPicker = [[UIImagePickerController alloc] init];
imgpPicker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
imgpPicker.mediaTypes = [NSArray arrayWithObjects:(NSString *)kUTTypeMovie,(NSString *)kUTTypeImage,nil];
popOverView = [[UIPopoverController alloc] initWithContentViewController:imgpPicker];
[popOverView presentPopoverFromRect:self.view.bounds inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
The error that appears on the debugger is signal SIGABRT:
*** Terminating app due to uncaught exception 'UIApplicationInvalidInterfaceOrientation', reason: 'Supported orientations has no common orientation with the application, and shouldAutorotate is returning YES'
*** First throw call stack:
(0x36a732a3 0x33e9a97f 0x36a731c5 0x3777d897 0x3777d6a1 0x3777d65b 0x3777ce1b 0x3777cb45 0x37735767 0x377355c7 0x377355c7 0x3772fe53 0x377177e5 0x377172cb 0x37b00b95 0x115313 0x378d6ccb 0x378000ad 0x3780005f 0x3780003d 0x377ff8f3 0x377ffde9 0x377285f9 0x37715809 0x37715123 0x3644d5a3 0x3644d1d3 0x36a48173 0x36a48117 0x36a46f99 0x369b9ebd 0x369b9d49 0x3644c2eb 0x37769301 0xe1763 0xe14c0)
libc++abi.dylib: terminate called throwing an exception
(lldb)
The privacy for the application is also set to ON in the settings.
Am i doing something wrong?
Any guidance or tips will be very helpful. Sorry if the question is very vague.. If need more information, I can provide...
In your code add:
- (BOOL)shouldAutorotate
{
return YES;
}
And go to the summary tab of your application and allow both portrait and landscape orientations.

Resources