presentViewController doesn't work on iOS7, app hangs - ios

I'm using GCD to make sure this happens on the main thread, but even that doesn't fix the issue.
- (void)showCat:(NSNotification *)notification {
dispatch_async(dispatch_get_main_queue(), ^{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UINavigationController *navVC = [storyboard instantiateViewControllerWithIdentifier:#"Cat"];
[self presentViewController:navVC animated:YES completion:^{
//this never happens on iOS7
}];
});
}
navVC is not nil.
Works fine on iOS8. On iOS7 the app just hangs. Memory usage continuously goes up until it crashes due to memory pressure.
What else could be the cause of this? presentViewController works fine in other areas of the app. This code is called when a notification is received.

Actually turned out there was some recursive code in viewDidLayoutSubviews of the presented view controller. Thanks to #matt for the tip. Not sure why this isn't also an issue in iOS8, but nevertheless the problem is fixed.
Goes to show that actually offering advice even if you don't have the entire code base of the project in front of you can still be helpful, rather than simply downvoting from your high horse.

Related

iOS app crashing after setting UIWindow rootViewController in iOS 9

My app was working great until running it on iOS 9.
In the AppDelegate, I check whether the user is logged in or not. If they're not logged in, I send them to the login screen with the following line:
self.window.rootViewController = [self.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:#"Login"];
After the user logs in, I attempt to send them to the main app with the following line:
self.window.rootViewController = [self.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:#"Tabs"];
This worked in iOS 8, but now it crashes the app. And it's a bad crash. The whole device has to reboot (although it's a very quick one, so I think it's more like a SpringBoard reboot or something).
I'm seriously at a loss as to why the first line works and the second doesn't. Any help is much appreciated!
EDIT
I ended up recreating the entire UIViewController flow that was crashing and it works fine now. As far as I can tell it was some strange bug in the new Xcode. Not considering this an answer, so if anyone has a true answer then feel free to share it.
Not sure why, but this works for me in iOS9. It might be that you're trying to do this already in the AppDelegate before the window has been properly loaded?
I've got a first ViewController in the storyboard and does this redirecting there instead.
UIViewController *viewController = [[UIStoryboard storyboardWithName:#"Storyboard"
bundle: nil] instantiateViewControllerWithIdentifier:#"viewController"];
[[[[UIApplication sharedApplication] delegate] window] setRootViewController:viewController];
The code to set the root view controller works in iOS9 without issues.
[[[[UIApplication sharedApplication] delegate] window] setRootViewController:viewController];
If you get a crash in that line, it surely means that the viewController initialization logic or any of its subviews are throwing at some point.
Problem is that working in the simulator the app will crash with no errors in the output. Best thing to do here is setting a breakpoint in the viewController logic (ie: viewDidLoad) and check what line is causing the error.

Warning: Attempt to dismiss from view controller <ViewController> while a presentation or dismiss is in progress

I´m new to Xcode but I keep on making some small apps to learn. I have run into a problem that only sometimes occurs with the message "Warning: Attempt to dismiss from view controller while a presentation or dismiss is in progress!" and the app then crash.
I have searched around and found some possible answers but no luck for me yet.
My code for back is:
- (IBAction)Back {
UIViewController *back = [[UIViewController alloc] initWithNibName:nil bundle:nil];
[self presentViewController:back animated:NO completion:NULL];
I understand that the problem is that I try to go from one viewcontroller to another before the presentation of the viewcontroller is done.
The strangest thing is that this sometimes isn´t any problem and the app works flawlessly.
Ok, I think you have trouble with the concept of navigation in iOS. First take a look at iOS Human Interface Guidelines: Navigation, and then read: Navigate with UINavigationController in iOS7 (don't worry about ios 7 or 8, they're both similar)
Overall, I really recommend watching Stanford's Developing iOS 7 apps for iPhone or following the newest one: Developing iOS 8 Apps with Swift to learn!

self.navigationController pushViewController hangs on iPad 8.1

While the following line works on iPhone 7.1/8.1, on iPad it only works on 7.1. On 8.1 the memory usage goes up and up until it crashes:
[self.navigationController pushViewController:detailController animated:YES];
This line happens here:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
OBDialogDetailViewController* detailController = [[OBDialogDetailViewController alloc] initWithOption:(OBSelectionFilterOption*)option];
[self animateChangeForView:nil atIndexPath:indexPath toRect:CGRectMake(0, 0, 0, 0) andNewHeight:0];
if (self.navigationController)
{
[self.navigationController pushViewController:detailController animated:YES];
}
}
Since I just got responsible for this application, thas has grown over years and has no documentation, I'm a little bit desperate. I searched and tried multiple answeres and solutions for two days now.
Please tell me what more information I can provide.
It will not happen in all scenarios. But couple of things I would like to mention :
I was trying to play an encrypted video (heavy file) on the destination viewcontroller of UINavigationController. Method which decrypts and loads the video on that viewcontroller's view takes time when I load it in viewDidLoad. In that case, please use the following code.
[self performSelectorInBackground:#selector(createVideoPlayer) withObject:nil];
[self performSelectorInBackground:#selector(createVideoPlayerControllerView) withObject:nil];
Please refer this link to manage memory issues even if you are using ARC.
This might not answer your question directly, but will certainly help you to debug. Please post whatever solution you get. Thanks.

Laggy presentation of SLServiceTypeFacebook

so I'm making a post to Facebook and want the user to select an image before doing that.
Once the image is picked and I show Facebook. Problem is, when I show Facebook straight away, without the image picking part, it looks fine. When I show it after picking the image, Facebook sharing appears animated, but laggy. As if the action has a very low framerate or something.
Here's my code:
self.portraitPicker = [[UIImagePickerController alloc] init];
#if !(TARGET_IPHONE_SIMULATOR)
self.portraitPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
#endif
[self.portraitPicker setDelegate:self];
self.portraitPicker.allowsEditing = YES;
[self presentViewController:self.portraitPicker animated:YES completion:nil];
Now when this is complete, I show the Facebook posting modally:
[picker dismissViewControllerAnimated:YES completion:^{
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook])
{
self.facebookController = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
[self.facebookController setInitialText:#"Some text"];
[facebookController addImage:pickedImage];
[self presentViewController:self.facebookController animated:NO completion:nil];
}
}];
I can do this in the didFinishPickingMediaWithInfo or the imagePickerControllerDidCancel, doesn't matter, the problem still comes up.
Being desperate, I tried:
Showing it on the main thread delayed
Showing it async
Showing it outside the dismiss-block
Showing it from the AppDelegate's rootviewcontroller instead
This is not Facebook-related as it happens with SLServiceTypeTwitter as well as with MFMessageComposeViewController.
Can't seem to do away with the laggy animation that ONLY happens showing the image picker. Does anyone know what's causing this?
Given the lack of response and similar issues, I figured the cause was my own architecture.
It turns out that one of my viewcontrollers' ViewDidAppear was called after the camera picker was displayed (as it became the active viewcontroller and consequently the inactive one, giving control back to the original viewcontroller).
Blocking the background calls and animation that happened in this viewDidAppear resolved the issue. I still don't know why calling it delayed (i.e. 10 seconds, or even 100 seconds into the future, when nothing was going on) still had the laggy appearence show up, but there it is.

How to call a view controller from AppDelegate in iOS

I am creating an iOS app in which I have the following requeriment: the app should show the login screen when it starts the first time and also that screen must also be shown when the app comes from the background to the foreground, in case it has been sent to background during run time.
I have handled to show the screen in both cases. However, when I do it and the app comes from the background, and I click the texfield to type my password, the app gets frozen, and it fails in a thread that I don't know what it means.
I call the screen to be shown when the app comes from background like this, in the applicationWillEnterForeground, in AppDelegate:
self.window=[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
RoomRootViewController* room = [[RoomRootViewController alloc] init];
[[self window] setRootViewController:room];
[self.window makeKeyAndVisible];
Is this the correct way to do so?
Thanks a lot in advance ! I am completely lost with this as I am very new in iOS, so any help will be very appreciated.
Attached in an image you can see where the app fails.
The code you are currently using is completely deleting the root view controller of your app window, in other words, you are deleting all the views and view controllers in your app. If you are not using ARC, this is just one huge memory leak. If you are, it's still not a very good idea.
In your applicationWillEnterForeground: method, try using this code instead:
RoomRootViewController* room = [[RoomRootViewController alloc] init];
[self.window.rootViewController presentViewController:room
animated:NO
completion:nil];
This will display the RoomRootViewController over the top of all your app's current views, instead of deleting them. You can then dismiss it like this:
[self.window.rootViewController dismissViewControllerAnimated:YES
completion:nil];
and easily return to the rest of your app.
It will be very messy if you are using this line of code
self.window=[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
It means every time you are creating new instance of UIWindow which will contain UIViewController and all other component each time. Which means when you go to background and comes to foreground the old window instance has been flushed off and it will contain new components that's why when you click on the UITextField it has been deallocated, The reason you are getting error. Don't create new instance of window and use the code as #PartiallyFinite does.
Hope this helps.

Resources