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

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];
...
}

Related

AppDelegate "unexpected nil window' error

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.

How to programmatically create UIView so that it does not overlap the status bar

I am using the following code in my app delegate to programmatically create the application's window and root controller:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = [[UIViewController alloc] init];
self.window.rootViewController.view = [[UIView alloc] init];
self.window.rootViewController.view.backgroundColor = [UIColor redColor];
return TRUE;
}
The code works fine, however the view associated to the root view controller overlaps the status bar, which I would like to avoid (see picture below).
How should I proceed? In particular I want to have a lightgray background for the status bar (similar to the apps created with a storyboard) and also handle orientation change correctly.
Thanks
Well, you can do something as following:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = [[UIViewController alloc] init];
self.window.rootViewController.view.backgroundColor = [UIColor whiteColor];
UIView *redView = [[UIView alloc] initWithFrame:CGRectMake(0,
[UIApplication sharedApplication].statusBarFrame.size.height,
[UIScreen mainScreen].bounds.size.width,
[UIScreen mainScreen].bounds.size.height)];
redView.backgroundColor = [UIColor redColor];
[self.window.rootViewController.view addSubview:redView];
[self.window makeKeyAndVisible];
return TRUE;
}
should look like this:

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?

Issues Starting in Landscape with IIViewDeckController as RootController on iPad

If I set a view deck controller as the AppDelegate window's root controller, when the app starts in landscape orientation on an iPad, the center view is displayed in it's Portrait orientation size and not resized to Landscape.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
IIViewDeckContoller *rootController = [IIViewDeckController new];
self.window.rootViewController = rootController;
self.window.backgroundColor = [UIColor blackColor];
[self.window makeKeyAndVisible];
}
However, if I create a simple controller as a root controller, and then present the view deck controller from this root controller, then everything seems to display just fine.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UIViewController *simpleRootController = [UIViewController new];
IIViewDeckContoller *deckController = [IIViewDeckController new];
self.window.rootViewController = simpleRootController;
self.window.backgroundColor = [UIColor blackColor];
[self.window makeKeyAndVisible];
// View Deck Controller seems to have issues when it is the root controller of the main window.
// Presenting it as a modal seems to do the trick.
[simpleRootController presentViewController:self.deckController animated:NO completion:nil];
}
Anyone else run into this issue? Is there a better way to solve this? I do not see the same behavior with the iPhone.
I've seen some people having success with the following method in IIViewDeckController:
- (CGRect) referenceBounds {
if (self.referenceView) {
return self.referenceView.bounds;
}
CGRect bounds = [[UIScreen mainScreen] bounds]; // portrait bounds
if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
bounds.size = CGSizeMake(bounds.size.height, bounds.size.width);
}
return bounds;
}
However, I'm not seeing anything change. I can't take the OP's advice of presenting the view controller due to some other restrictions.

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.

Resources