iPad airplay display shows black screen when I create a new UIWindow - ios

[EDIT]
I restarted the iPad and it fixed the issue. I'm leaving it here because stack overflow discouraged deleting the question
I have a weird thing happening on iPad Air 2. Using the method mentioned in https://developer.apple.com/library/ios/documentation/WindowsViews/Conceptual/WindowAndScreenGuide/UsingExternalDisplay/UsingExternalDisplay.html
I create a new UIWindow object for the secondary display connected through AirPlay.
- (void)checkForExistingScreenAndInitializeIfPresent {
if ([[UIScreen screens] count] > 1)
{
// Get the screen object that represents the external display.
UIScreen *secondScreen = [[UIScreen screens] objectAtIndex:1];
// Get the screen's bounds so that you can create a window of the correct size.
CGRect screenBounds = secondScreen.bounds;
self.secondWindow = [[UIWindow alloc] initWithFrame:screenBounds];
self.secondWindow.screen = secondScreen;
NSLog(#"Show external window");
// Set up initial content to display...
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Test" bundle:[NSBundle mainBundle]];
UIViewController *controller = [storyboard instantiateInitialViewController];
self.secondWindow.rootViewController = controller;
// Show the window.
self.secondWindow.hidden = NO;
}
}
When I run this code on an iPhone 5s, The code works perfectly and the secondary window is initialized. However, when I run this code from Xcode on the iPad Air 2, I only see a black screen. If the app is not run through Xcode, the app launches on the iPad but on the AirPlay display it only shows the home screen with the app icon highlighted. The audio is still routed through AirPlay.
Any help would be greatly appreciated.

Normally we change our UIWindow Color like this:
[UIApplication sharedApplication].keyWindow.backgroundColor = [UIColor myColor];
You can set your self.secondWindow color as:
secondWindow.backgroundColor = [UIColor whiteColor];

This was a ridiculous case and the solution to it was just as ridiculous. I restarted the iPad and the issue went away.

Related

Xcode App won't load view sometimes

my project runs without storyboards, so im loading my view inside AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window = window;
self.window.rootViewController = [[SYLoginController alloc] init];
[self.window makeKeyAndVisible];
return YES;
}
It used to work on iPhone 6 sim 9.3 but now, on all simulators it only shows a black screen. But on my iPhone 6 Device it works. Whereas on another iPhone 6 it also shows a black screen. Those two iPhones are literally the same 16gb iPhone 6 bought at nearly the same time.
In SYLoginControllers viewDiDLoad I'm logging the text of one of the buttons. Only on my device it prints the text, on all simulators and the other iPhone it prints (null), so i assume that the xib is not properly loaded.
SYLoginController is a UIViewController, and the related xib holds a UIView with its FilesOwner set to SYLoginController. I really can't see why it only works on this particular device. Also i tried [[SYTabBarController alloc] initWithNibName:#"SYLoginController" bundle:nil], this also does not work...
Did you tried to wrap it arround a Navigation Controller?
SYLoginController *syVC = [[SYLoginController alloc]initWithNibName:#"SYLoginController" bundle:nil];
UINavigationController *nav = [[UINavigationController alloc] syVC];
self.window.rootViewController = nav;
Also check again if Custom Class is set to SYLoginController in the XIB-File. And the View is connected to the Files Owner.

Airplay IOS multiple view controller

I am trying to implement an application with a number of viewcontrollers presented through a hierarchy with different viewing on the iPad and Airplay device. I am using objective C and Storyboard.
I have updated the app delegate and I can see my first controller presented on both displays but then I get stuck when I push through the next view controllers. The iPad shows the next controllers but the Airplay gets stuck on the first one.
Does anyone have experience in building such an app and would be willing to share some lights on how to do this ?
This is my code snippet in my appdelegate:
//Managing connection and disconnection of screens.
-(void) screenConnectionStatusChanged {
if ([[UIScreen screens] count] == 1) {
secondaryWindow.hidden=YES;
secondaryWindow.rootViewController = nil;
} else {
UIScreen *newScreen = [[UIScreen screens] lastObject];
self.secondaryWindow = [[UIWindow alloc] initWithFrame:[newScreen bounds]];
self.secondaryWindow.screen = newScreen;
self.secondaryWindow.hidden = NO;
self.secondaryWindow.layer.contentsGravity = kCAGravityResizeAspect;
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
LoginViewController *vc = [storyboard instantiateInitialViewController];
[secondaryWindow setRootViewController:vc];
[secondaryWindow setHidden:NO];
[secondaryWindow makeKeyAndVisible];
}
}
Thanks

iPhone 6 / iPhone 6+ launch screen size issue

I want to optimize my app for iPhone 6 and iPhone 6+
But I have a launch screen size problem.
I created a simple project, and AppDelegate's code is:
#import "AppDelegate.h"
#import "ViewControllerOne.h" //xib screen size is 4 inch.
#import "ViewControllerTwo.h" // xib screen size is 4.7 inch.
#import "ViewControllerThree.h" // xib screen size is 5.5 inch.
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
if ([UIScreen mainScreen].bounds.size.height == 568.0) {//4 inch
ViewControllerOne *first = [[ViewControllerOne alloc]init];
UINavigationController *navigation = [[UINavigationController alloc]initWithRootViewController:first];
self.window.rootViewController = navigation;
}
else if ([UIScreen mainScreen].bounds.size.height == 667.0){//4.7inch
ViewControllerTwo * second = [[ViewControllerTwo alloc]init];
UINavigationController *navigation = [[UINavigationController alloc]initWithRootViewController:second];
self.window.rootViewController = navigation;
}
else if ([UIScreen mainScreen].bounds.size.height == 736.0){//5.5inch
ViewControllerThree *third = [[ViewControllerThree alloc]init];
UINavigationController *navigation = [[UINavigationController alloc]initWithRootViewController:third];
self.window.rootViewController = navigation;
}
}
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
#end
When I run iPhone 6 or iPhone 6+ simulator, it always appears 4inch screen when I run this project.(I included three launch image(Default-667h#2x.png, Default-736#3x.png, Default-568#2x.png) also.
What I have to do to resolve this problem.
I checked others question that similar to mine, and used their code, but all of those not works. That is maybe my technical skills relatively row.
Once you specify the images in Assets Catalog you will see the right images
Go to YourAppTarget> General> App Icons and Launch Images> Launch Image Source > Use asset Catalog
and then drag the appropriate size for each device.
In addition to adding images you can also add a Launch Screen File. This is a .XIB file that allows you to specify constraints in addition of launch images. It only works on iOS8. To support iPhone 6 and 6+, we only add this file and specify constraints:
To set the Launch Screen File add it to your project:
File > New > User Interface > Launch Screen
Then go to: YourAppTarget > General > App Icons and Launch Image s> Launch Screen File > Set your newly created image
You will still need launch images for Retina 4" and 3.5", if you are supporting iOS 7.

load different xib for iphone5 not working in device

Possible duplicate:
How to make xib compatible with both iphone 5 and iphone 4 devices
Can I use two xibs with one viewcontroller - re: porting to iPhone 5
I have developed an iPhone app which now I'm trying to update giving it iPad and iPhone5 support.
I now there are lots of posts talking about how to handle this but none of them are working for me. 3.5'' iPhones and iPads load the xib they need but 4'' iPhone doesn't (although in simulator works fine), so here is how I handle it:
First of all I create three different xib files for each viewController (ViewController.xib, ViewController~ipad.xib and ViewController-568.xib). In the 4'' xib one I set the size of the view as "Retina 4 Full Screen".
Then I have used this to load the appropiate xib. It also may be relevant to say that in the AppDelegate I set the didFinishLaunchingWithOptions like this:
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
NSString *nibName = [UIViewController nibNamedForDevice:#"ViewController"];
self.viewController = [[BPViewController alloc] initWithNibName:nibName bundle:nil];
UINavigationController *navCont = [[UINavigationController alloc] initWithRootViewController:self.viewController];
self.window.rootViewController = navCont;
[self.window makeKeyAndVisible];
self.viewController.navigationController.navigationBar.barStyle = UIBarStyleBlack;
return YES;
}
As I said it works like a charm in the simulator but in real device only iPad's and 3.5'' xib are load properly. The iPhone5 still is showing the up and down black bar...
You appear to be using the wrong suffix on your nibs/assets, use -568h#2x instead of -568h.
Alternatively i always switch various iOS assets / positions in code using:
if([ [ UIScreen mainScreen ] bounds ].size.height == 568 )
{
//iPhone 5.0 specific code
}
else
{
//None iphone 5 code
}
Its also worth noting at this stage that using more nib files to do this will result in a bigger .IPA. So its worth reading up on how autolayout works and going for that approach to keep executable size down.

XCode 4.5 / iOS6 : orientation issue with my iPad app in Landscape mode

I just opened my iPad project on XCode 4.5. My app is designed to run in Landscape mode. It works perfectly on previous versions of XCode. But on XCode 4.5, it is rotated of 90° (quarter turn) with a empty area on the right side of the screen (and my view has the correct size but goes out of the screen). It looks like this:
I checked the following posts but didn't help:
orientation issue in ios6
ios6 Rotation issue from landscape to portrait mode
Set orientation to landscape mode in xcode 4.5 GM IOS 6
Anybody had this issue ?
Any help would be appreciated !
Thanks everybody for your replies. I finally found a solution.
First, check that all your launch images have the correct orientation and correct size in the target summary menu (blue icon of your project => target => summary => scroll at the bottom) ; if the size or orientation is not correct, you get a warning on the launch image which is not set properly.
Up to now, I had a project with this structure (old XCode fashion):
AppDelegate.h and .m
RootViewController.h and .m
a MainWindow-Iphone.xib and MainWindow-iPad.xib (with the RootViewController linked in Interface Builder ; see the screenshot below with the yellow/brown icon (with a square inside) relative to the RootViewController)
Here below a screenshot of what it looked like:
And here is what was the code in the applicationDidFinishLaunching: method of my AppDelegate:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[window addSubview:[rootViewController view]];
[window makeKeyAndVisible];
}
What I did is to be closer to the structure you get when you create an empty project with XCode 4.5. Consequently:
I removed the MainWindow.xib and MainWindow-iPad.xib and now created my window programatically (clearer and better to make sure that it fits the size of any screen)
I removed the "Main nib file base name" and "Main nib file base name (iPad)" keys which were defined in my Info.plist (and set to MainWindow.xib and MainWindow-iPad.xib)
I added empty RootViewController_iPhone.xib and RootViewController_iPad.xib
I changed the code in my applicationDidFinishLaunching method like this:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
NSLog(#"applicationDidFinishLaunching");
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
self.rootViewController = [[RootViewController alloc] initWithNibName:#"RootViewController_iPhone" bundle:nil];
} else {
self.rootViewController = [[RootViewController alloc] initWithNibName:#"RootViewController_iPad" bundle:nil];
}
self.window.rootViewController = self.rootViewController;
[self.window makeKeyAndVisible];
}
And now, everything works fine ! Orientation is correct on iPad ! And it is much more clear than before :) I even didn't have to change the deprecated methods like
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
By the way, to make sure that all your views will be full screen (on iPhone 5) make sure that your views are set to the mode "Scale to fill" in Interface Builder and that "Autoresize subviews" is clicked. If some of your views do not scale to full screen, it is probably due to the order in which one you create your controllers/views (the superView sends a notification to its subviews only when it (the superView) is created). To solve this easily, simply add the following code in the - (void)viewDidLoad method:
CGRect screenBounds = [[UIScreen mainScreen] bounds];
[self.view setFrame:CGRectMake(0,0,screenBounds.size.width,screenBounds.size.height)];
or use:
[self presentModalViewController:myViewController animated:TRUE];
instead of:
[self.view.superview addSubview:myViewController.view];
presentModalViewController indeed sends a resizing notification to the subviews.
Hope this will help !
Make sure you are setting the window.rootViewController as well. I had the same issue, but this line fixed it for me:
MainViewController *mainView = [[MainViewController alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
window.rootViewController = mainView;
I had a similar problem on an app I upgraded. I haven't found it documented but it seems there has been a change. What I ended up finding is the new window doesn't seem to know about rotation or size until after it is made key and visible. I was able to move my frame setting to immediately after makeKeyAndVisible and everything worked. I hope that helps you.
[[yourViewController view] setFrame:CGRectMake(0.0, 0.0, 1024.0, 768.0)];
[[yourViewController view] setTransform:CGAffineTransformTranslate(CGAffineTransformMakeRotation(0.5*M_PI),128.0,128.0)];
If you are using Storyboards one easy hack is to use the loadView method. It is called before viewDidLoad. Just go to your Storyboard and delete the associated view as you are going to create it programmatically in loadView. Then return to the view controller class and copy the following code:
- (void)loadView
{
// You can adjust the view size and location here. If using full screen use the following code. If you have a tab bar for example and also want to account for the top default iPad bar, use: CGRectMake(0, 20, 1024, 699) instead.
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1024, 748)];
view.backgroundColor = [UIColor whiteColor];
view.autoresizesSubviews = NO;
self.view = view;
}
A few simple steps in order will solve this problem for you.
First, in AppDelegate.m, check if you're adding your rootViewController as a subView. That is, instead of this,
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[window addSubview:[navigationController view]];
[window makeKeyAndVisible];
}
do something like this
- (void)applicationDidFinishLaunching:(UIApplication *)application {
window.rootViewController = navigationController;
[window makeKeyAndVisible];
}
if you're setting a navigation controller as your root view controller.
Second, if you need to get control of the rotation methods within your navigationController's pushed viewControllers, create a category for UINavigationController like so:
#import "UINavigationController+Rotation.h"
#implementation UINavigationController (Rotation)
- (BOOL)shouldAutorotate {
BOOL result = self.topViewController.shouldAutorotate;
return result;
}
- (NSUInteger)supportedInterfaceOrientations {
return self.topViewController.supportedInterfaceOrientations;
}
#end
Now, these two orientation methods for iOS 6 upwards
-(BOOL)shouldAutorotate and
-(NSUInteger)supportedInterfaceOrientations
will get called within your classes.
This is necessary because the older rotation methods such as
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
have been deprecated from iOS 6.
So lastly, you'll need to implement these in your view controllers; something like this:
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
if you want to allow your view controller to rotate and support all orientations.
The other orientation masks are:
UIInterfaceOrientationMaskPortrait
UIInterfaceOrientationMaskLandscapeLeft
UIInterfaceOrientationMaskLandscapeRight
UIInterfaceOrientationMaskPortraitUpsideDown
UIInterfaceOrientationMaskLandscape and
UIInterfaceOrientationMaskAllButUpsideDown

Resources