How to change the Storyboard entry point for varying size classes - ios

I have an iPhone application (using a Storyboard) and want to add a iPad version. The iPad version should have a different entry point since the it has a different hierarchy and workflow.
Is it possible to change the storyboard entry point for different size classes? Or would it be better to use a separate Storyboard for the iPad version in this case?

In your case, you can define a different xib for only the Initial ViewController and in the code, you can check the device type in the - application:didFinishLaunchingWithOptions:, you can use
[[InitialViewController alloc] initWithNibName:#"YourNibNameAccordingToScreen" bundle:nil];
After this, as you mentioned in the comments, your other screens are adaptive to different screen sizes.So, this approach would solve your problem.

Related

Some time App take iphone XIB to load controller

I am creating an application using Apple's new swift language.
Application is universal, so that I created XIB with '~' operator. Like "MyView~iphone.xib" and MyView~ipad.xib" . But sometimes, even when my application is running in iPad it loads iPhone nib.
I have tried lots of option but still facing the same issue.
People may think this never happens but I am facing this issue.
It would be better to see the code but i guess your solution is like this
BOOL isPad = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
UIViewController *myViewController = [[UIViewController alloc] initWithNibName:isPad?#"MyView~ipad.xib":#"MyView~iphone.xib" bundle:nil];
Hey try using size classes in Interface Builder and you won't need different xibs for both iPhone and iPad. You can take advantage of size classes and setting constraints in storyboard for each of the size class. I recommend you watching WWDC 2014: Session 216.
I have had an issue like this objective C but that was way back in iOS 6, I don't know whether this could fix your issue but
Try renaming the files as
MyView~iphone.xib for iPhone
MyView.xib for iPad
Instead of
MyView~iphone.xib
MyView~ipad.xib
I would advise you to use Size classes since it is future proof.

why storyboard ui elements not showing on UIViewController in xcode 6?

I am new to IOS development. I am developing an app for IOS 8 devices. I used storyboard for my design yesterday my storyboard showing all UI design but today morning it show blank UIViewController no UI element vision please see in screen shot and very strange thing is that when i run my app all ui element visible in my device. I google but dont find any solution please help me out. Thank you in advance.
It looks to me like you are using size class and you went into a particular size class and added these views. Now you are back in Any size class, so the views are not there (that is why they are greyed out in the document outline at the left). They are available only for that particular size class. If you switch back to it again, whatever it was, you will see them again. Basically, you have created conditional views - the condition being that they are present only when that particular size class situation is the case.
In other words, if you want your layout to apply in the general case, you want to start by creating and editing it under Any size classes. Only then do you switch to a particular size class and modify the layout for that particular size class.
when i run my app all ui element visible in my device
Yes, because on your device the particular size class situation matches the size class you were editing when you added those views. So there they are. That seems to me to prove my guess is right.
I have the same issue while copy a ViewController to another storyboard.
Fixed by following steps:
1: Select the viewController
2: Click on 5th Tab
3: Set the simulated size to Fixed.
Select install:
Since all components [like label,textfield,buttons] are in disable mode, one select Installed check mark its will be enable again adjust constrain accordingly.
The size must be the same, in all xcode storyboard
In my case, it was due to me setting alpha to 0.0 and forgetting it.

STORYBOARD EXCEPTION - Storyboard doesn't contain a view controller with identifier

I am currently developing an iOS application for both iPhone and iPad. I'm trying to show a NavigationController to make a module that shows files. In an iPhone it works just fine, but I can´t get it to work in iPad.
I'm getting the following error:
'Storyboard (<UIStoryboard: 0x919b200>) doesn't contain a view controller with identifier 'FilesNavigation''
and this is the code:
case 10: // Files
{
UINavigationController *navigationController = [storyboard instantiateViewControllerWithIdentifier:#"FilesNavigation"];
FilesViewController *filesViewController = [storyboard instantiateViewControllerWithIdentifier:#"Files"];
[navigationController pushViewController:filesViewController animated:YES];
self.slidingViewController.topViewController = navigationController;
break;
}
And in my storyboard I have already set the Storyboard ID for the navigation controller.
>##Custom Class
>Class: UINavigationController
>##Identity
>Storyboard ID: FilesNavigation
I used this code for another case on the switch/case block for other module and it works for iPad too, its the first time that I have this error.
I figured it out, the problem was that the Storyboard wasn't updating in the device.
Uninstall the app from the simulator/iPhone/iPad
Product > Clean
Build & Run
As stated in #T0m_Twt's answer in this question
In the right pane, in the identity inspector section give a storyboard Id to your Navigation Controller.
I took a screenshot for you
Here's another case:
There are two localized storyboards. Only one of them has the view controller you want.
By chance, do you have a storyboard for iPhone and a different one for iPad? If you do, then the iPad one might not have a storyboard with that identifier. Also when running on an iPad, set a break point in your code and verify what your "storyboard" object is.
I use a category on UIStoryboard that will give me the storyboards for each platform.
I can use [UIStoryboard storyboardHome] and that will determine if it needs iPad or iPhone specific and return that to me. I also ensure my storyboards follow proper naming. So I would have Home_iPad and Home_iPhone.
TL;DR - clear everything and remove old version of the app as well, if there's any.
It may sound crazy, but suppose that if you have changed target name which changed bundle name as well, you might have both the old and new version of the app installed in the simulator / device, and this might cause trouble for the UIStoryboard instance failed to instantiate some view controllers, which might eventually cause the trouble described in the question. To solve it, you need to remove all related apps or simply reset the simulator / device.

How to make a developed app for iPhone5 to work on older iPhones (Screens) [duplicate]

This question already has answers here:
How to develop or migrate apps for iPhone 5 screen resolution?
(30 answers)
Closed 9 years ago.
I have an app developed and tested on my iPhone 5, but now I would like to make it work on older iphones as 4 and 4s. The functionalities work in the same way, but there are some buttons which do not appear because of the screen resolution.
Is there any way I can make the same .xib to work on different screen resolutions?
a) You can always design your interfaces (.xib) with anchor or elastic coordinates, so if the screen is bigger/smaller, the coordinates are relative to one of the edges of the screen.
b) You can WRAP the entire screen in a UIScrollView and let the user SCROLL to access all buttons.
These are the easiest. a) will give you more headaches. I would go for b) because it's more time efficient.
For b) I also recommend that you TRY the interface in a smaller screen and check that the hidden content is PARTIALLY VISIBLE, so users have a HINT that there's "something down there".
EDIT
This is an example for initializing a viewController with different xib files.
- (id)init
{
int model = ... //some model inspection method;
switch(model) {
case iphone3g:
return [self initWithNibName:#"iphone3g.xib" bundle:nil];
case iphone4:
case iphone4s:
return [self initWithNibName:#"iphone4x.xib" bundle:nil];
... //etc
I would suggest Apple's WWDC videos on auto layout, those will help with using the same XIB. It really depends on your interface and what you're looking to do, there's no one right answer.
You could also create two XIBs, one for 480 height and another for 568, then write in code a bit to ask the device what size it is, and load the appropriate XIB. This can be useful if auto layout just seems to be a big pain with what you're implementing.

Universal app - how to?

I'm using Xcode 4.2 and in the process of writing a universal app. I selected SingleView Application template when starting with a new project. XCode added ViewController1.h, ViewController1.m, ViewController1_iphone.xib and ViewController1_iPad.xib. I need to add more UIs and clicked on the File...New...New File and selected UIViewController subClass template and seeing two checkboxes (Targeted for iPad, With Xib for User Interface).
What should I do here to support both iPad and iPhone while at the same time have a common .h and .m files that share the same code. Do I need to add code to check whether it is a iPad or iPhone by doing this in my view controllers?
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
} else {
}
Also, I have seen people talking about ~iPad and ~iPhone. What is this all about?
If I understand correctly, do I have to design the UI separately both for iPad and iPhone due to different screen sizes?
I'm totally confused here.
Please help.
You can either add two nibs (one for ipad and one for iphone), or you can add one nib that will properly scale for either interface. Normally you'd add two nibs if you're making a view that will cover all or most of the screen, and you'd add one nib if you're making something small that will, perhaps, be fullscreen on iphone but displayed in a popover on ipad.
The tilde suffixes ~ipad and ~iphone are described under the heading “iOS Supports Device-Specific Resources” in the Resource Programming Guide. Notice that the suffixes are entirely lower-case, not camel-case as you wrote in your question. This matters because iOS uses a case-sensitive filesystem.
When you get a path for a resource using an NSBundle message like -[NSBundle pathForResource:ofType:] or -[NSBundle URLForResource:withExtension:], iOS will first look for the resource file with a suffix of ~ipad or ~iphone, depending on the current device. For example, suppose you do this:
NSString *path = [[NSBundle mainBundle] pathForResource:#"setup" ofType:#"plist"];
If you run this on an iPhone-type device (including an iPod touch), or on the simulator in iPhone mode, iOS will first look in your app bundle for a file named setup~iphone.plist. If it finds such a file, it will return the path of that file. If it doesn't find that file, it will instead return the path to setup.plist.
If you this on an iPad-type device, or on the simulator in iPad mode, iOS will first look in your app bundle for a file named setup~ipad.plist. If it finds such a file, it will return the path of that file. If it doesn't find that file, it will instead return the path to setup.plist.
All of the other APIs that get resources from bundles are built on top of NSBundle, so they all benefit from this device-specific lookup. That means if you use +[UIImage imageNamed:], it will automatically use a device-specific image, if you have one in your bundle. And if you use -[NSBundle loadNibNamed:owner:options:], it will automatically load a device-specific nib (.xib) file, if you have one in your bundle.
This simplifies your code, if you use the suffixes. If you create MyViewController~ipad.xib and MyViewController~iphone.xib, your app will automatically load the correct one for the current device. You don't have to check the user interface idiom; NSBundle checks it for you. (You could also use the names MyViewController~ipad.xib and MyViewController.xib and get the same effect.)
Now, you may have noticed that when you created your “universal” project, Xcode gave your project files named ViewController1_iPhone.xib and ViewController1_iPad.xib, which do not use the tilde suffixes, and it included code to look at the user interface idiom and choose a filename accordingly. Why does the universal project template do this? I don't know, but it is stupid. I suggest you fix the filenames to use the tilde suffixes and rip out the code that checks the user interface idiom.
I would recommend moving your .xib files to Storyboards, one for iPhone and one for iPad. They put a lot of joy back into development and are easy to learn.
Then, assign your custom class to your view controllers and link your UI elements to your code. If you do this for both storyboards, then they can both share the same code by referencing a common .h/.m file.
In the project settings, you then assign the appropriate storyboards to the iPhone/iPad deployment info once the app has been configured for universal development.
It's more or less up to you how you choose to implement things and structure things, but I tend to work with the following idea :
Ignore the 'Target for iPad' and 'With Xib' options (unless not using storyboards. See later)
Create a parent view controller that holds all shared code. E.G. MainViewController
Create 2 subclasses of this for both iPad and iPhone. E.G. MainViewController_iPhone and MainViewController_iPad (you could use MainViewController~iPhone which you mentioned. Simply a matter of naming preference here)
Any code that you want shared between iPhone and iPad, stick in the MainViewController parent class, and anything specific to each device place in the appropriate subclass
Generally you shouldn't really need to test if you're running on an iPhone or iPad. That's not to say that it's wrong and you shouldn't do it, but by separating the classes like this, you shouldn't really need to. But what I like to do is check what device I'm running on when I handle what orientations the device can handle, and put this in the shared parent view controller.
As for your UI, you've got 3 options.
- Use storyboards (I'd recommend this)
- Use separate XIB files
- Code everything manually
Depending on how much you now about iOS, coding everything manually can be more efficient, but will most likely take you longer. Using interface builder is nice and simple, although any customisations you want to make you'll still need to do in code but that's fine.
I'd suggest using storyboards so that you don't have loads of different XIB files. It also simplifies the split between iPhones and iPads, as you simply have 2 files for your interface. One will have all of your screens for the iPhone, and one will have all the screens for the iPad. iOS will automatically load the right storyboard at startup so you don't have to do anything. Then, to get your view controller and view, you can do something like :
MainViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"MainViewControllerIdentifier"];
Note that the identifier is specified inside the storyboard.
Hopefully this helps slightly, but if you have more questions just fire away :)
Here is what you want:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
storyboard = [UIStoryboard storyboardWithName:#"ViewController1_iphone" bundle:nil];
}
else if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
storyboard = [UIStoryboard storyboardWithName:#"ViewController1_ipad" bundle:nil];
}
If you name your nib files MyNib.xib and MyNib~ipad.xib, the required nib will be automatically loaded, depending on the device your app is running on. However, it is not always necessary to create different nibs. If you don't require much customization, and it can be solved with the autoresizingMasks or you are setting some frames programmatically, it can be solved with only one nib. If you check the "targeted for ipad" part, your view in the nib will be larger, and the grouped tables look a little differently, but I don't know of any other difference in the outcome.
Hope this helps!

Resources