AppDelegate "unexpected nil window' error - ios

EDIT:
People downvoting this because I used sleep, this is why I used it:
Making the launch image display longer xcode
The window size is small. If you don't want to answer, don't downvote it.
I just want to get rid of this error.
unexpected nil window in _UIApplicationHandleEventFromQueueEvent,
_windowServerHitTestWindow: UIClassicWindow: ; frame = (0 0; 320 568); userInteractionEnabled = NO; gestureRecognizers = NSArray: > ; layer =
UIWindowLayer: >>
I have an iOS app which runs on both iPad and iPhone in landscape mode. It runs fine on the ipad simulators but on the iphone 5s and iphone 6s (which I have tested so far), I get this error:
unexpected nil window in _UIApplicationHandleEventFromQueueEvent,
_windowServerHitTestWindow: UIClassicWindow: ; frame = (0 0; 320 568); userInteractionEnabled = NO; gestureRecognizers = NSArray: > ; layer =
UIWindowLayer: >>
This is the AppDelegate code.. I don't have any problem on ipad.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// [NSThread sleepForTimeInterval:3];
[application setStatusBarHidden:YES];
self.window = [UIWindow new];
if([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
self->_loginViewController = [[LoginViewController alloc] initWithNibName:#"somename~ipad" bundle:nil];
} else if([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) {
self->_loginViewController = [[LoginViewController alloc] initWithNibName:#"somename~iphone" bundle:nil];
}
[[NSUserDefaults standardUserDefaults] setValue:#(NO) forKey:#"_UIConstraintBasedLayoutLogUnsatisfiable"];
self.window.rootViewController = nil;
self.window.rootViewController = self->_loginViewController;
[[UINavigationBar appearance] setBarTintColor:[UIColor blackColor]];
[[UINavigationBar appearance] setTranslucent:NO];
[self.window makeKeyAndVisible];
[self.window setFrame:[[UIScreen mainScreen] bounds]];
return YES;
}

I figured out that I was getting the "unexpected nil window" error because I was using Asset catalog for my landscape application.
https://developer.apple.com/library/content/technotes/tn2244/_index.html#//apple_ref/doc/uid/DTS40009012
Avoid using asset catalogs to manage the launch images of landscape
applications. Except for launch images used by the iPhone 6 Plus,
asset catalogs assume that all iPhone launch images are for the
portrait orientation.

Related

iPhone app Custom UIWindow wrong frame in iPad Landscape orientation

I am writing an iPhone app using custom UIWindow.(xCode6.1, iOS8.1)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
application.statusBarOrientation = UIInterfaceOrientationLandscapeRight;
CGRect bounds = [[UIScreen mainScreen] bounds];
_window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, bounds.size.height, bounds.size.width)];
[_window setBackgroundColor:[UIColor greenColor]];
[_window makeKeyAndVisible];
return YES;
}
It targets iPhone, Landscape only. All works fine on all iPhone devices, but when it runs on iPad, the UIWindow frame is broken.
Any advice?

self.window not working inside view controller

For iOS 7, I had status bar problem. For that I solved it by using below code in Appdelegate
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
[[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleLightContent];
self.window.clipsToBounds =YES;
self.window.frame = CGRectMake(0,20,self.window.frame.size.width,self.window.frame.size.height-20);
self.window.bounds = CGRectMake(0,0, self.window.frame.size.width, self.window.frame.size.height);
}
All is working perfectly.
Only it gives problem while taking photo.
When I open camera or photo gallery, I still see status bar and because of that I see half of the navigation title as shown below.
Any idea how can I overcome this error?
The problems are :
Photo Gallery/ Camera comes like above image
If I click cancel, my view is shifted 20px up automatically.
Instead of:
self.window
Use this:
[[self view] window]
Try Like this:
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
[[UIApplication sharedApplication] setStatusBarStyle: UIStatusBarStyleLightContent];
self.view.window.clipsToBounds =YES;
self.view.window.frame = CGRectMake(0,20,self.view.window.frame.size.width,self.view.window.frame.size.height-20);
self.view.window.bounds = CGRectMake(0,0, self.view.window.frame.size.width, self.view.window.frame.size.height);
}
I guess you are using the UINavigationController. There is nothing to do with the frame nor to do something with the Status Bar, If you are using UINavigationController. Please prefer the below code to set the UINavigationController along with Status bar set up. Else you can display the code, Will help you fix this.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[UIApplication sharedApplication] setStatusBarHidden:NO];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[ExViewController alloc] initWithNibName:#"ExViewController" bundle:nil];
self.window.rootViewController = self.viewController;
self.mainViewNavigation = [[UINavigationController alloc] initWithRootViewController:self.viewController];
self.window.rootViewController = mainViewNavigation;
[self.window addSubview:self.mainViewNavigation.view];
[self.window makeKeyAndVisible];
return YES;
}
I faced this problem wih one of my project. We didn't even have the xib for many classes. So all I could do is reset the frame once again in the delegate functions.
[self.navigationController dismissViewControllerAnimated:YES
completion:^{
[self.navigationController.view setFrame:CGRectMake(self.navigationController.view.frame.origin.x, [UIApplication sharedApplication].statusBarFrame.size.height, self.navigationController.view.frame.size.width, [[UIScreen mainScreen] bounds].size.height-[UIApplication sharedApplication].statusBarFrame.size.height)];
}];
I put this in the finish/cancel delegate methods of photo/camera picket, mail picker.

iOS UILaunchImageFile: some 4-inch-screen users see black borders

Some of my users seem to consistently see a clipped screen when running my app on their 4-inch devices. It may be limited to iPod Touch 5g users, and seems to occur on iOS6 and iOS7 (I am still investigating). I have what I think is a simple and correct UILaunchImageFile configuration, and it works fine on my iPhone 5 and in all the simulators. Any ideas?
Info.plist:
...
<key>UILaunchImageFile~ipad</key>
<string>UILaunchImage-iPad</string>
<key>UILaunchImageFile~iphone</key>
<string>UILaunchImage</string>
...
App product filesystem:
MyApp.app/
...
Info.plist
UILaunchImage-568h#2x.png (640x1136)
UILaunchImage-iPad.png (768x1024)
UILaunchImage-iPad#2x.png (1536x2048)
UILaunchImage.png (320x480)
UILaunchImage#2x.png (640x960)
...
[EDIT: my startup code, in MyAppDelegate]
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
// screen.bounds is the whole display size;
// screen.applicationFrame is smaller when you show the status bar
UIScreen * screen = [UIScreen mainScreen];
CGRect screenBounds = screen.bounds;
CGRect applicationFrame = screen.applicationFrame;
self.window = [[[UIWindow alloc] initWithFrame:screenBounds] autorelease];
// load main ui
MyUIViewController * main = [[[MyUIViewController alloc] initWithNibName:#"MyUIViewController" bundle:nil] autorelease];
UIView * rootView = [[[UIView alloc] initWithFrame:screenBounds] autorelease];
main.view = rootView;
[main loadIfNeeded];
self.viewController = main;
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
...
}

What is the best way to display a UIView at the top of the screen in either iOS 6.1 or 7?

Here is a simple program to display a blue colored view at the top of the screen.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
UIViewController* vc = [[UIViewController alloc] init];
CGFloat y = 20;
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) {
y = 0;
}
UIView* sample = [[UIView alloc] initWithFrame:CGRectMake(0, y, 768, 100)];
sample.backgroundColor = [UIColor blueColor];
[vc.view addSubview:sample];
self.window.rootViewController = vc;
[self.window makeKeyAndVisible];
return YES;
}
I have logic in there to set the y variable to either 0 or 20 if iOS version is 7 or 6 and under. Is there a better way to do this?
iOS 7 brings several changes to how you lay out and customize the appearance of your UI. The changes in view-controller layout, tint color, and font affect all the UIKit objects in your app. In addition, enhancements to gesture recognizer APIs give you finer grained control over gesture interactions.
Please refer, apple doc
In my case, I decided to do exactly as you've mentioned. It is not "as clean as", it takes more work, but it gives you a fine precision, in case you're not targeting too many devices.

Why is this ImageView not being released?

i have a splash page that is displayed on app startup that my client wants me to keep visible for x amount of time. Everything is working great except the image is never released?
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSString *fileLocation = [[NSBundle mainBundle] pathForResource:#"splash_page" ofType:#"png"];
NSData *imageData = [[NSData alloc] initWithContentsOfFile:fileLocation];
UIImage *launchImage = [[UIImage alloc] initWithData:imageData];
[imageData release], imageData = nil;
UIImageView *launchImageView = [[UIImageView alloc] initWithImage:launchImage];
launchImageView.frame = CGRectMake(0,
0,
[[UIScreen mainScreen] bounds].size.width ,
[[UIScreen mainScreen] bounds].size.height);
launchImageView.tag = 121;
[launchImage release], launchImage = nil;
[self.window addSubview:launchImageView];
[launchImageView release], launchImage = nil;
[self.window makeKeyAndVisible];
[self performSelector:#selector(initApp) withObject:nil afterDelay:kInitDelay];
return YES;
}
- (void)initApp
{
[[UIApplication sharedApplication] setStatusBarHidden:NO];
UIImageView *launchImageView = (UIImageView*)[self.window viewWithTag:121];
[launchImageView removeFromSuperview];
RootNavController *navController = [[RootNavController alloc] initRootController];
self.rootNavController = navController;
[self.window addSubview:navController.view];
[navController release], navController = nil;
}
It is my understanding that removeFromSuperview calls release on the view so this should be released however i can still see a Malloc of 524kb in Intruments Object Allocation tool which im sure is the image. Responsible Library = libRIP.A.dylib and the Responsible Caller ripl_Create.
If i comment out the splash page code and launch the NavController directly i dont have that 524kb.
Any ideas?
Why don't you use the Default.png as your splash screen? Renaming your "Splash_page.png" to "Default.png" will automatically show the splash page on load and then just add UIImageView (with Default.png) to the MainWindow and after x time launch your rootViewController.

Resources