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
Related
I'm want to make an app that uses a UISplitViewControler on the iPad (as far as I understand it's only available on the iPad) but I want the app to be universal.
The setup is like this:
I have a UITableView (as a master view) and when I select a row it should display a detail view of that cell. I am using a Storyboard and I can't figure out how to implement the split view only for the iPad.
What would be the easiest way to achieve that? Thanks.
You don't need two storyboards to do this.You can use them both in a single storyboard.For iphone ,we normally use a class SWRevealViewController(if you are new to iOS coding ..:)) for side menu and splitviewcontroller for ipad.We can also use SWRevealViewController for ipad as well.It depends on your requirement.
For universal apps,create viewcontrollers using size Classes(usually we use any height any width for universal apps ).
change these size classes and create different viewcontrollers for ipad and iphones as required.In most cases any height any width will do the job.
After creating the viewcontrollers,in the appdelegate ,using the instantiateViewcontrollerWithIdentifier method, load the required viewcontroller.
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
// The device is an iPad running ios 3.2 or later.
}
else {
// The device is an iPhone or iPod touch.
}
For ipad load the splitviewcontroller. and swrevealviewcontroller for iPhone.
This is the core basics.If you need any more information,let me know.
EDIT
Have you seen an arrowmark ath the initial VC(viewcontroller) in the storyboard?This vc is loaded first after the launch screen.In my app,I have a home screen which is common to both iphone and ipad(using size classes as mentioned above).So I can set this vc as the initial VC.In this case I don't have to do anything in the appdelegate.But if I have a different home screen for ipad,then I can make a condition check in the appdelegate didFinishLaunchingWithOptions
You can load the First screen like this.You should follow through splitVC tutorilal and swrevealcontroller tutorial to set the side menu.You should load the SWrevealVC or splitViewcontroller only if the first screen contains the side menu.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UISplitViewController *split = [storyboard instantiateViewControllerWithIdentifier:#"SplitViewController"];
[AppDelegate setRootController:split storyboard:storyboard actiontype:0];
}
else if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *split = [storyboard instantiateViewControllerWithIdentifier:#"SWrevealVC"];
[AppDelegate setRootController:split storyboard:storyboard actiontype:-1];
}
return YES;
}
+(void)setRootController:(UIViewController*)controller
storyboard:(UIStoryboard*)storyboard actiontype:(int) actiontype;
{
if ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad && actiontype == 0)
{
UISplitViewController *splitViewController = (UISplitViewController *)controller;
//splitViewController.presentsWithGesture = false;
UINavigationController *masterNavigationController = [splitViewController.viewControllers objectAtIndex:0];
SideMenuViewController *controller = (SideMenuViewController *)masterNavigationController.topViewController;
controller.splitViewController = splitViewController;
splitViewController.delegate = (id)controller;
}
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[UIView
transitionWithView:appDelegate.window
duration:0.5
options:UIViewAnimationOptionAllowAnimatedContent
animations:^(void) {
BOOL oldState = [UIView areAnimationsEnabled];
[UIView setAnimationsEnabled:NO];
appDelegate.window.rootViewController = controller;
[UIView setAnimationsEnabled:oldState];
}
completion:nil];
}
The code may look lengthy,but take it simple.You can only understand the logic if u do things.
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
{
CGSize iosScreenSize = [[UIScreen mainScreen] bounds].size;
if (iosScreenSize.height == 667) {
UIStoryboard *iPhone6 = [UIStoryboard storyboardWithName:#"iPhone6" bundle:nil];
UIViewController *initialViewController =[iPhone6 instantiateInitialViewController];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen]bounds]];
self.window.rootViewController = initialViewController;
[self.window makeKeyAndVisible];
}
return YES;
}
return YES;
}
That is all i added in AppDelegate.m. Im using Xcode 6.1. I did this because i'm not using auto layout so I created a separate ViewController and called it iPhone6.h and iPhone6.m and a created a storyboard for it calling it iPhone6. I've connected the iPhone6 storyboard to iPhone 6.h and .m so i don't understand why when i'm loading the iPhone6 simulator I automatically get the "Application windows are expected to have a root view controller at the end of application launch" error. Why am I getting it?
First of all check for value of initialViewController. if it getting null value then you are not selected any controller as initialView controller.
For select controller as initialViewController you have to go to story board and then select controller which you want to load initially and select option which is shown in image below.
In certain cases I want to set specific a specific inital view.
Basically to divide between onboarding and real use of the app.
Currently, I'm using this code to do so:
- (void)checkWhereUserIsInOnboarding {
UIStoryboard *mainstoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
if([authStatus isEqual:#3]){ // did get past certain point in onboarding
UIViewController *initialViewController = [mainstoryboard instantiateViewControllerWithIdentifier:#"connectNav"];
self.window.rootViewController = initialViewController;
[self.window makeKeyAndVisible];
}
else if(currentUser.objectId == nil){ //no user; he/she is new to the app
UIViewController *initialViewController = [mainstoryboard instantiateViewControllerWithIdentifier:#"loginNav"];
self.window.rootViewController = initialViewController;
[self.window makeKeyAndVisible];
}
else{//fully featured users
UIViewController *initialViewController = [mainstoryboard instantiateViewControllerWithIdentifier:#"tabbarcontroller"];
self.window.rootViewController = initialViewController;
[self.window makeKeyAndVisible];
}
}
Since I need to check this multiple times during the lifetime of the app, this function runs in the ApplicationDidBecomeActive method.
However, when I'm instantiating one of these VC's as initial view, I always get a black screen for about 100ms, after which the app goes on to the right screen.
How do I solve this?
A "black screen" seems to imply your app is being killed off in the background. If you swap out of the app then invoke the application switcher does your app show as a black screen?
As a starting point it's probably a good to run it under Instruments and watch things like memory etc. to make sure IOS isn't shutting it down.
I am trying to:
detect device (iPhone 3.5", iPhone 4", iPad, ect)
load a different storyboard depending on what device and what size the application is running on.
I have watched some tutorials but I am still not getting it, can someone please type/show what code needs to go in the app delegate to achieve these goals.
Thanks!
Try something like this in your app delegate:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
UIStoryboard *storyboard = nil;
if([[UIDevice currentDevice]userInterfaceIdiom]==UIUserInterfaceIdiomPhone)
{
if ([[UIScreen mainScreen] bounds].size.height == 568.0f)
{
storyboard = [UIStoryboard storyboardWithName:#"iPhone5s" bundle:nil];
}
else
{
storyboard = [UIStoryboard storyboardWithName:#"iPhone4" bundle:nil];
}
}
else
{
storyboard = [UIStoryboard storyboardWithName:#"iPad" bundle:nil];
}
[window setRootViewController:[storyboard instantiateInitialViewController]];
[window makeKeyAndVisible];
}
I wish to create an app with multiple storyboards to support iPhone5, iPhone4 (and below) and iPad screens.
I did the following:
I created 3 storyboards, one per each setting.
I cleared the "main storyboard" field in the project interface.
I cleared the "Main storyboard file base name" field in the app info.plist file.
I entered the following code to the AppDelegate "didFinishLaunchingWithOptions" method:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIStoryboard* appStoryboard = nil;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
if (IS_IPHONE_5) //a macro capturing the screen size
{
appStoryboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone5" bundle:nil];
}
else
{
appStoryboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone4" bundle:nil];
}
}
else if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
appStoryboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPad" bundle:nil];
}
UIViewController* viewController = [appStoryboard instantiateInitialViewController];
[self.window setRootViewController:viewController];
[self.window makeKeyAndVisible];
return YES;
}
The application is running and not crashing, but I get a black screen.
What am I missing / doing wrong?
You didn't initialize the window.
Just add
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];