Base Internalization without storyboard in XCode 5.0 - ios

I prefer not to work with Storyboard, so my projects start from an empty project, then in the appDelegate I write code like this:
MyViewController *VC = [[MyViewController alloc]init];
self.window.rootViewController = VC;
This intro just to tell you that if I try to activate Base Internationalization and I load the controller in that way I obtain just an empty controller. The xib seems not to be loaded.
Let's say that I want just to setup my project to be multi-language in the next future. So I don't add further languages, I keep only English.
These are the steps that I do to activate the Base Internat.
Selecting the xib file and pushing "Localize"
Localize it for the only Language available, English
From "Project" -> tab "info" I select "Use base Internationalization", selecting the only xib available.
Back to the xib, I activate the localizable string for English language (at the moment in the "Localization Box" of the xib I see "base" and "english". Eventually I add a Label to the xib.. just to be sure that the strings file will be created correctly.
Now, if I launch the App.... the xib isn't correctly loaded!
I hate this situation because it would be great to have this project setup for future translations... but it seems to work only if I work with a Storyboard.
Do you have some suggestions or have you experienced something similar with your projects?

Related

Converting iOS Storyboard to tvOS [duplicate]

I have an iPhone application which has a storyboard. Now I want to provide an iPad application too. So I asked me whether there is a function which helps me convert my iPhone storyboard to an iPad storyboard.
To be specific:
Is there a similar function or is there only the manual way ?
I found out a kind of solution:
Duplicate your iPhone-Storyboard and rename it MainStoryboard_iPad.storyboard
Close Xcode and then open this file any text editor.
Search for targetRuntime="iOS.CocoaTouch"and change it to targetRuntime="iOS.CocoaTouch.iPad"
Change the code in the MainStoryboard_iPad.storyboard from:
<simulatedScreenMetrics key="destination" type="retina4"/> to
<simulatedScreenMetrics key="destination"/>
Now save everything and reopen Xcode. The iPad-Storyboard has the same contents as the iPhone-file but everyting could be disarranged.
This saved me hours - hopefully this will help you
If you had created a universal project, by default empty iPad storyboard would have been created, you just have to select iPhone storyboard select all (Command+A), copy (Command+C) and paste it on iPad storyboard. Make sure to move the entry point from the empty storyboard to newly copied storyboard before compiling.
That didn't quite work for me. I did something a little bit different.
Create a new story board file for the iPad version
Open both the new file and the file i want to copy in textwrangler (text editor)
Copied the xml text from old file to the new file between these xml tags
First Tag <scenes> <!--Contents View Controller-->
Paste Here
End Tags </class> </classes>
That worked for me. I got a new layoutout with all my outlets connected, which alone saved me a few hours.
From reading many threads on stackoverflow i discovered the solution is-
1.Duplicate your iPhone-Storyboard and rename it MainStoryboard_iPad.storyboard
2.right click on the storyboard -> “open as” -> “Source Code”.
3.Search for targetRuntime="iOS.CocoaTouch"and change it to targetRuntime="iOS.CocoaTouch.iPad"
5.Search for <simulatedScreenMetrics key="destination" type="retina4"/> and change it to to <simulatedScreenMetrics key="destination"/>
4.Now save everything and right click on MainStoryboard_iPad.storyboard “open as” ->"IOS StoryBoard"
5. you may also have to change your constraints.
Thats all you have done.
1. Create New Storyboard file with MainStoryboard_iPad.storyboard
2. Copy All the views from MainStoryboard and paste to MainStoryboard_iPad.storyboard
1 - Create your "MainStoryboard_iPad.storyboard";
2 - Right-click on you "MainStoryboard_iPhone.storyboard" and "Open as -> Source Code". Copy everything;
3- Right-click on you "MainStoryboard_iPad.storyboard" and "Open as -> Source Code". Paste everything. Now Search and change:
targetRuntime="iOS.CocoaTouch" to targetRuntime="iOS.CocoaTouch.iPad"
type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" to type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.iPad.XIB"
4 - Save. Now reopen but using the interface builder. You will only have to re-arrange.
This method can be used for .xib files too
This is going the other way, but I was able to do a select all & copy in my iPad storyboard (~35 scenes) and paste it into my iPhone storyboard. The scene sizes were automatically adjusted. I only saw two problems, I had to replace UISplitViewController (since it's only iPad), and the default background became transparent instead of gray (still working on fixing that properly, without manually setting the background for everything).
EDIT: It seems the default background for UITableView in the Attributes inspector is rather strange. I had to manually set the background to "Group Table View Background Color" for grouped table views, and "White Color" for non-grouped table views. It then was displayed as "Default" (I assume since it then matched a hardcoded value). -- Actually, even easier, changing from "Grouped" to "Static" and back seems to reset the default color.
Here's something that saved me hours and might help those of you with Python skills.
I've been building an app for the last two months, focused on just iPad iterating the UX with the team.
Today focused on building out iPhone version, followed the steps above (thanks!) but I didn't want to then have to resize all the ui elements from iPad dimensions in the visual storyboard editor.
So I wrote this little python jig script to scan through the storyboard file for x, y, width, height and scale everything down by by ratio 320./768. Allowed me then to just focus on fine adjustments.
Copy your iPad storyboard into a new file. (e.g. iPhoneStoryboard.storyboard)
Run the script below with the copied storyboard filename as the first parameter.
Will generate output file with suffix _adjusted.storyboard (e.g. iPhoneStoryboard.storyboard_adjusted.storyboard)
Hope it helps...
import re
import sys
import math
afile = sys.argv[1]
scale = 320./768.
number_pattern = '[-0-9]+(.[0-9]+)?'
#width_pattern = 'width="[-0-9]+( ?px)?"'
width_pattern = 'width="[-0-9]+(.[0-9]+)?( ?px)?"'
height_pattern = 'height="[-0-9]+(.[0-9]+)?( ?px)?"'
x_pattern = 'x="[-0-9]+(.[0-9]+)?( ?px)?"'
y_pattern = 'y="[-0-9]+(.[0-9]+)?( ?px)?"'
def replacescaledvalue(scale,pattern,sometext,replacefmt) :
ip = re.search(pattern, sometext, re.IGNORECASE)
if(ip) :
np = re.search(number_pattern,ip.group(0))
if(np) :
val = float(np.group(0))
val = int(math.floor(val*scale))
sval = replacefmt+str(val)+'"'#+'px"'
newtext = re.sub(pattern,sval,sometext)
return newtext
else :
return sometext
fin = open(afile)
fout = open(afile+"_adjusted.storyboard", "wt")
for line in fin:
newline = line
newline = replacescaledvalue(scale,width_pattern,newline,'width="')
newline = replacescaledvalue(scale,height_pattern,newline, 'height="')
newline = replacescaledvalue(scale,x_pattern,newline, 'x="')
newline = replacescaledvalue(scale,y_pattern,newline, 'y="')
# print newline
fout.write( newline )
fin.close()
fout.close()
For Xcode10
Just duplicate Main.storyboard
Then re-name files to Main_iPad.storyboard and Main_iPone.storyboard
Set appropriate names in .plist
4.Just select the proper .storyboard to configure
Go to your Target Summary and change devices to universal,
then go down and set the ipad version to any storyboard you like including a copied and renamed one if you like.
Just as a quick gotcha note to those who may have had my issue with this:
My issue:
The storyboard content copied over nicely to a new board file I added. However, it would not put changes over to my provisioned iPad. Noticing that I had to switch over the designated storyboard for the build target (see image) let the changes show.
I'd post an image if I had the points, but the setting is located in:
Project navigator on the left side source menu, root target of project (center pane) general tab, (second subhead) deployment info, with the iPad button tab selected.
From there, choose your storyboard under "main interface."
Thanks for the post, I hope this mention helps a snag somewhere.
Just for fun, on XCode 5.1 and iOS 7.1 I also needed to change the values of "toolVersion" and "systemVersion" to this:
toolsVersion="5023" systemVersion="13A603"
Without this, the new storyboard file wouldn't compile
Using the XCode6 Size Classes you no longer need to convert the storyboard to iPad.
The same Storyboard can be used for both the iPhone and the iPad, saving you from keeping two files up to date.
The resulting storyboard is compatible with iOS7+.
Read more about this here:
https://developer.apple.com/library/ios/recipes/xcode_help-IB_adaptive_sizes/chapters/AboutAdaptiveSizeDesign.html#//apple_ref/doc/uid/TP40014436-CH6-SW1
Use size classes to enable a storyboard or xib file to work with all available screen sizes. This enables the user interface of your app to work on any iOS device.
This functionality is now built-in. For example, if one changes the project settings in Deployment Info -> Devices from iPhone to Universal, the following dialog will show up:
There is a really simple solution for Xcode versions that support size classes (Tested in Xcode 7 which is the current version at the time of writing). Check the "use size classes" checkbox on a storyboard file (File Inspector), confirm that dialog that appears. Then uncheck that same checkbox - Xcode will ask you if you want to use this storyboard with an iPhone or iPad, and convert the screens in it appropriately. No need to directly edit the storyboard file. For both iPad and iPhone, just copy the same storyboard and configure one for iPad and one for iPhone using the described method.
And Before someone suggest to use size classes - while great, they are less convenient for heavily customized UI, such as games etc
I followed this thread when I was hit with the same issue yesterday. The steps I followed
For Xcode 5.1, I had to do some cleanup of iPhone storyboard like missing reuseIdentifiers of Table cells, provide story board id for every controller, remove unused scenes.
Copy MainStoryboard_iPhone.storyboard to MainStoryboard_iPad.storyboard.
Using vi editor - changed targetRuntime="iOS.CocoaTouch" to targetRuntime="iOS.CocoaTouch.iPad"
Change the code in the MainStoryboard_iPad.storyboard from: <simulatedScreenMetrics key="destination" type="retina4"/> to <simulatedScreenMetrics key="destination"/>
Open the project in Xcode.
Changed the Deployment devices to Universal - Chose the option of NOT copying the iPhone Storyboard.
Xcode will default the Deployment Target to 7.1, took care of the deprecated functions.
To fix the misplaced view error in iPad Storyboard - Changed the Frame Layout for Controllers giving errors.
That was it.. Thanks all for your help..
The easiest and most reliable way to do this is to copy paste from your iPad storyboard.
Create a new storyboard and name it something like MainStoryboard_ipad.
Make your app a Universal app by setting the Devices property to Universal on the Summary page of the Target properties for your project.
Open your iPhone storyboard and select all and copy
Open your iPad storyboard and paste.
You'll have to go about resizing, but it can be faster than recreating the whole storyboard.
A Different Approach
Add an empty-View-Controller with Navigation-Controller in the iPad-Storyboard
Change the Class to the Class of your first ViewController used for iPhone, "fooViewController"
Add the Storyboard-Identifier in the iPhone-Storyboard "fooViewController_storyboard_identifier" for the first ViewController
Go to "fooViewController.m"
Add bool Variable bool nibWasLoadForIpad=false
Go to viewDidLoad-Method
if ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad && !nibWasLoadForIpad)
{
nibWasLoadForIpad=true;
UIStoryboard* Storyboard_iphone=[UIStoryboard storyboardWithName:#"Main_iPhone" bundle: nil];
fooViewController *controller = [Storyboard_iphone instantiateViewControllerWithIdentifier:#"fooViewController_storyboard_identifier"];
[self.navigationController pushViewController:controller animated:YES];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
}
(ps. Know problem is that the view-backgrounds will be set to white)
You should create a bug report with Apple. You can say it's a duplicate of mine (10167030) which has been open since September 2011. The frustrating thing from my point of view is that the feature existed in Xcode 3...
Thanks for the answers everybody.
I followed the above steps but when I ran the app under the simulator or my iPad it kept on just using the iPhone storyboard.
For some reason, when I changed the target device to be Universal instead of iPhone, Xcode (v5.0) didn't update the app-Info.plist file to include the iPad storyboard, so I had to manually add the following entry (using the plist editor in Xcode):
Main storyboard file base name (iPad) ==> MainStoryboard_iPad
I just change (additionally to the answer from #tharkay):
<device id="ipad9_7" orientation="landscape">
and works great !
I use this in XCode 8.3.3

how does LaunchScreen.storyboard redirect to Main.storyboard

I'm newbie of iOS developer, and I know that is very simple question but I really can't understand reason.
when I build SingleViewApplication, Xcode auto generate LaunchScreen.storyboard and Main.storyboard,
but I can't find any code like [self.navigationController pushViewController:] which may choose that what view controller enter stack as last one of top-level view,
I only find ViewController.{h,m} as first and see no logic that change view from LaunchScreen.storyboard to Main.storyboard.
could anyone help? thanks..
Main.storyboard file and LaunchScreen is define in your project property.
you can find it by click on project in xcode and then in below target you can find this two name you can choose your own by selecting dropdown given beside label.
and other redirecting to LaunchScreen to Main.storyboard you can refer info.plist file in your project and also AppDelegate.h and AppDelegate.m
Most probably the iOS first looks for LaunchScreen.storyboard file and shows it for some time and when it is done with it, it looks for Main.storyboard.
These names are hardwired in the plist as mentioned by Tejas in his answer and you can change these.
I don't think the the LaunchScreen.storyboard is pushing the Main.storyboard. Everything is managed behind the scenes and you can't change this behavior.
What you can change is the initial View Controller in your Main.storyboard so that it is instantiated immediately after the LaunchScreen.storyboard disappears and the app is fully loaded.

Impossible to localize an app

Localization is driving me crazy!
I would like to have my application in english, and in french. So here is what I have in my project settings:
To begin, let's try to translate my storyboard:
Because my storyboard is in english (base language?), I've just ticked Base and French.
I guess Localizable Strings are easier to give to translators, so I choose "Localizable Strings"
Now my problem is the following:
When I change the text of a label in the base storyboard
Nothing happens, the text is not changed when launching the app.
If I edit Main.strings, nothing happens.
It's like another storyboard is used (a past one), but if I check my Finder, I don't have any other storyboard (even hidden).
Last weird thing, I have this in my "Copy bundle ressources":
If I remove it and add it again, the result is still the same.
I don't know which storyboard my app is using, I can't find it in Finder, and my "Copy bundle ressources" section is telling that a storyboard is missing, even if I add it again.
Any suggestions?
I'm solved the problem by clean project and clean build folder and then in edit schema I setted configuration by change Run Options by changing application language and application region (in my case Italian) as writed here

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!

Converting Storyboard from iPhone to iPad

I have an iPhone application which has a storyboard. Now I want to provide an iPad application too. So I asked me whether there is a function which helps me convert my iPhone storyboard to an iPad storyboard.
To be specific:
Is there a similar function or is there only the manual way ?
I found out a kind of solution:
Duplicate your iPhone-Storyboard and rename it MainStoryboard_iPad.storyboard
Close Xcode and then open this file any text editor.
Search for targetRuntime="iOS.CocoaTouch"and change it to targetRuntime="iOS.CocoaTouch.iPad"
Change the code in the MainStoryboard_iPad.storyboard from:
<simulatedScreenMetrics key="destination" type="retina4"/> to
<simulatedScreenMetrics key="destination"/>
Now save everything and reopen Xcode. The iPad-Storyboard has the same contents as the iPhone-file but everyting could be disarranged.
This saved me hours - hopefully this will help you
If you had created a universal project, by default empty iPad storyboard would have been created, you just have to select iPhone storyboard select all (Command+A), copy (Command+C) and paste it on iPad storyboard. Make sure to move the entry point from the empty storyboard to newly copied storyboard before compiling.
That didn't quite work for me. I did something a little bit different.
Create a new story board file for the iPad version
Open both the new file and the file i want to copy in textwrangler (text editor)
Copied the xml text from old file to the new file between these xml tags
First Tag <scenes> <!--Contents View Controller-->
Paste Here
End Tags </class> </classes>
That worked for me. I got a new layoutout with all my outlets connected, which alone saved me a few hours.
From reading many threads on stackoverflow i discovered the solution is-
1.Duplicate your iPhone-Storyboard and rename it MainStoryboard_iPad.storyboard
2.right click on the storyboard -> “open as” -> “Source Code”.
3.Search for targetRuntime="iOS.CocoaTouch"and change it to targetRuntime="iOS.CocoaTouch.iPad"
5.Search for <simulatedScreenMetrics key="destination" type="retina4"/> and change it to to <simulatedScreenMetrics key="destination"/>
4.Now save everything and right click on MainStoryboard_iPad.storyboard “open as” ->"IOS StoryBoard"
5. you may also have to change your constraints.
Thats all you have done.
1. Create New Storyboard file with MainStoryboard_iPad.storyboard
2. Copy All the views from MainStoryboard and paste to MainStoryboard_iPad.storyboard
1 - Create your "MainStoryboard_iPad.storyboard";
2 - Right-click on you "MainStoryboard_iPhone.storyboard" and "Open as -> Source Code". Copy everything;
3- Right-click on you "MainStoryboard_iPad.storyboard" and "Open as -> Source Code". Paste everything. Now Search and change:
targetRuntime="iOS.CocoaTouch" to targetRuntime="iOS.CocoaTouch.iPad"
type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" to type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.iPad.XIB"
4 - Save. Now reopen but using the interface builder. You will only have to re-arrange.
This method can be used for .xib files too
This is going the other way, but I was able to do a select all & copy in my iPad storyboard (~35 scenes) and paste it into my iPhone storyboard. The scene sizes were automatically adjusted. I only saw two problems, I had to replace UISplitViewController (since it's only iPad), and the default background became transparent instead of gray (still working on fixing that properly, without manually setting the background for everything).
EDIT: It seems the default background for UITableView in the Attributes inspector is rather strange. I had to manually set the background to "Group Table View Background Color" for grouped table views, and "White Color" for non-grouped table views. It then was displayed as "Default" (I assume since it then matched a hardcoded value). -- Actually, even easier, changing from "Grouped" to "Static" and back seems to reset the default color.
Here's something that saved me hours and might help those of you with Python skills.
I've been building an app for the last two months, focused on just iPad iterating the UX with the team.
Today focused on building out iPhone version, followed the steps above (thanks!) but I didn't want to then have to resize all the ui elements from iPad dimensions in the visual storyboard editor.
So I wrote this little python jig script to scan through the storyboard file for x, y, width, height and scale everything down by by ratio 320./768. Allowed me then to just focus on fine adjustments.
Copy your iPad storyboard into a new file. (e.g. iPhoneStoryboard.storyboard)
Run the script below with the copied storyboard filename as the first parameter.
Will generate output file with suffix _adjusted.storyboard (e.g. iPhoneStoryboard.storyboard_adjusted.storyboard)
Hope it helps...
import re
import sys
import math
afile = sys.argv[1]
scale = 320./768.
number_pattern = '[-0-9]+(.[0-9]+)?'
#width_pattern = 'width="[-0-9]+( ?px)?"'
width_pattern = 'width="[-0-9]+(.[0-9]+)?( ?px)?"'
height_pattern = 'height="[-0-9]+(.[0-9]+)?( ?px)?"'
x_pattern = 'x="[-0-9]+(.[0-9]+)?( ?px)?"'
y_pattern = 'y="[-0-9]+(.[0-9]+)?( ?px)?"'
def replacescaledvalue(scale,pattern,sometext,replacefmt) :
ip = re.search(pattern, sometext, re.IGNORECASE)
if(ip) :
np = re.search(number_pattern,ip.group(0))
if(np) :
val = float(np.group(0))
val = int(math.floor(val*scale))
sval = replacefmt+str(val)+'"'#+'px"'
newtext = re.sub(pattern,sval,sometext)
return newtext
else :
return sometext
fin = open(afile)
fout = open(afile+"_adjusted.storyboard", "wt")
for line in fin:
newline = line
newline = replacescaledvalue(scale,width_pattern,newline,'width="')
newline = replacescaledvalue(scale,height_pattern,newline, 'height="')
newline = replacescaledvalue(scale,x_pattern,newline, 'x="')
newline = replacescaledvalue(scale,y_pattern,newline, 'y="')
# print newline
fout.write( newline )
fin.close()
fout.close()
For Xcode10
Just duplicate Main.storyboard
Then re-name files to Main_iPad.storyboard and Main_iPone.storyboard
Set appropriate names in .plist
4.Just select the proper .storyboard to configure
Go to your Target Summary and change devices to universal,
then go down and set the ipad version to any storyboard you like including a copied and renamed one if you like.
Just as a quick gotcha note to those who may have had my issue with this:
My issue:
The storyboard content copied over nicely to a new board file I added. However, it would not put changes over to my provisioned iPad. Noticing that I had to switch over the designated storyboard for the build target (see image) let the changes show.
I'd post an image if I had the points, but the setting is located in:
Project navigator on the left side source menu, root target of project (center pane) general tab, (second subhead) deployment info, with the iPad button tab selected.
From there, choose your storyboard under "main interface."
Thanks for the post, I hope this mention helps a snag somewhere.
Just for fun, on XCode 5.1 and iOS 7.1 I also needed to change the values of "toolVersion" and "systemVersion" to this:
toolsVersion="5023" systemVersion="13A603"
Without this, the new storyboard file wouldn't compile
Using the XCode6 Size Classes you no longer need to convert the storyboard to iPad.
The same Storyboard can be used for both the iPhone and the iPad, saving you from keeping two files up to date.
The resulting storyboard is compatible with iOS7+.
Read more about this here:
https://developer.apple.com/library/ios/recipes/xcode_help-IB_adaptive_sizes/chapters/AboutAdaptiveSizeDesign.html#//apple_ref/doc/uid/TP40014436-CH6-SW1
Use size classes to enable a storyboard or xib file to work with all available screen sizes. This enables the user interface of your app to work on any iOS device.
This functionality is now built-in. For example, if one changes the project settings in Deployment Info -> Devices from iPhone to Universal, the following dialog will show up:
There is a really simple solution for Xcode versions that support size classes (Tested in Xcode 7 which is the current version at the time of writing). Check the "use size classes" checkbox on a storyboard file (File Inspector), confirm that dialog that appears. Then uncheck that same checkbox - Xcode will ask you if you want to use this storyboard with an iPhone or iPad, and convert the screens in it appropriately. No need to directly edit the storyboard file. For both iPad and iPhone, just copy the same storyboard and configure one for iPad and one for iPhone using the described method.
And Before someone suggest to use size classes - while great, they are less convenient for heavily customized UI, such as games etc
I followed this thread when I was hit with the same issue yesterday. The steps I followed
For Xcode 5.1, I had to do some cleanup of iPhone storyboard like missing reuseIdentifiers of Table cells, provide story board id for every controller, remove unused scenes.
Copy MainStoryboard_iPhone.storyboard to MainStoryboard_iPad.storyboard.
Using vi editor - changed targetRuntime="iOS.CocoaTouch" to targetRuntime="iOS.CocoaTouch.iPad"
Change the code in the MainStoryboard_iPad.storyboard from: <simulatedScreenMetrics key="destination" type="retina4"/> to <simulatedScreenMetrics key="destination"/>
Open the project in Xcode.
Changed the Deployment devices to Universal - Chose the option of NOT copying the iPhone Storyboard.
Xcode will default the Deployment Target to 7.1, took care of the deprecated functions.
To fix the misplaced view error in iPad Storyboard - Changed the Frame Layout for Controllers giving errors.
That was it.. Thanks all for your help..
The easiest and most reliable way to do this is to copy paste from your iPad storyboard.
Create a new storyboard and name it something like MainStoryboard_ipad.
Make your app a Universal app by setting the Devices property to Universal on the Summary page of the Target properties for your project.
Open your iPhone storyboard and select all and copy
Open your iPad storyboard and paste.
You'll have to go about resizing, but it can be faster than recreating the whole storyboard.
A Different Approach
Add an empty-View-Controller with Navigation-Controller in the iPad-Storyboard
Change the Class to the Class of your first ViewController used for iPhone, "fooViewController"
Add the Storyboard-Identifier in the iPhone-Storyboard "fooViewController_storyboard_identifier" for the first ViewController
Go to "fooViewController.m"
Add bool Variable bool nibWasLoadForIpad=false
Go to viewDidLoad-Method
if ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad && !nibWasLoadForIpad)
{
nibWasLoadForIpad=true;
UIStoryboard* Storyboard_iphone=[UIStoryboard storyboardWithName:#"Main_iPhone" bundle: nil];
fooViewController *controller = [Storyboard_iphone instantiateViewControllerWithIdentifier:#"fooViewController_storyboard_identifier"];
[self.navigationController pushViewController:controller animated:YES];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
}
(ps. Know problem is that the view-backgrounds will be set to white)
You should create a bug report with Apple. You can say it's a duplicate of mine (10167030) which has been open since September 2011. The frustrating thing from my point of view is that the feature existed in Xcode 3...
Thanks for the answers everybody.
I followed the above steps but when I ran the app under the simulator or my iPad it kept on just using the iPhone storyboard.
For some reason, when I changed the target device to be Universal instead of iPhone, Xcode (v5.0) didn't update the app-Info.plist file to include the iPad storyboard, so I had to manually add the following entry (using the plist editor in Xcode):
Main storyboard file base name (iPad) ==> MainStoryboard_iPad
I just change (additionally to the answer from #tharkay):
<device id="ipad9_7" orientation="landscape">
and works great !
I use this in XCode 8.3.3

Resources