I am just about to start a universal iOS application. I want to make this application using interface builder only.
Can some one suggect how can I arrange the two nib files? Whenever I create a class only one xib file is created, but I want two xib files, one for iPhone and the other for iPad application as this a universal application.
Also can you suggest which approach would be better i.e. making UI for this universal application through interface or using coding.
Just add another xib file to the project. You can start by making a copy of the first version you make, or with a blank xib.
To ensure correct xib is loaded at runtime you have a few options. I prefer to overload nibName on UIViewController, but you can also just call initWithNibName:, passing the correct nib name.
If you overload nibName, it might be something like this:
- (NSString*) nibName
{
return UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone ? #"myphonenib" : #"mypadnib";
}
Personally given a choice, I prefer using xib, as the purpose of them is to "hide" GUI code making "function" code uncluttered..also "WYSIWYG" UI design kicks it for speed of development.
As for adding XIB...do As TomSwift suggest, just add them later
or as I did, do them on bulk later...i.e.
develop iphone bits first
Make copy of project
Convert copy to iPad
Rename Appdelegate & xib with your naming standard e.g *iPad suffix
Retrofit copied into your universal original.
(Note making sure you get all references changes and correct can be tidious & backup everything :)
Good luck.
Related
I'm trying to build a library that will allow for dynamic loading of Localizable.strings files. If the views are being developed programmatically, then it's not a problem, as I could build a separate NSBundle, store the .strings files inside, and use NSLocalizedStringFromTableInBundle.
The problem I'm having lies with Storyboards. I haven't managed to find a way to specify which .strings file to load from (rather than using the default .strings that Apple uses).
Does anyone know of a solution for this? It doesn't even have to follow the same approach, as long as I can dynamically update the strings on a Storyboard. (The strings will be pulled down from an external source via API call upon app launch)
Loading strings from a separate bundle/strings source
In order to overcome the issue I had, I created IBOutlets for each object on the Storyboard's collection of views. Within each view's implementation file, I programmatically set the text/values of each object by using NSLocalizedStringFromTableInBundle, which allows me to specify a custom bundle, which can be populated with strings files.
In the event that a project has both programmatic and storyboard developed views, this approach also allows for the usage of only one Localizable.strings file, rather than mixing Storyboard-generated files, and files used only for programmatic views (if applicable).
Loading strings into an app via API call
Unfortunately, the above approach doesn't allow for strings to be downloaded from an external source via API call. The reason for this being, Apple doesn't allow for any files in the app bundle to be edited after being built.
Because of this, the solution would be to build out a data structure within the app's DocumentsDirectory, and edit this whenever necessary, then force the app to use this file/library in order to get localized strings. Not a pretty solution, but it's the best approach I can think of.
I tried to turn a xib project which is downloaded from iOS Developer Library of Apple, into a pure code one for further use, but it didn't work.
I wonder what should I pay attention to when I do this kind of conversion, and I wonder it will help me improve my skill of iOS developing.
Converting the Xib file into pure code part is not a very big task, you just need to be carefully replace the items created via Interface builder by your code part. You can follow this sequence while converting such projects :-
1) Display the elements made via IB with your code.
2) Make sure the delegates and datasources to be connected via code if they were connected via IB.
3) Check for the IBActions, if any to be replaced.
4) Lastly, if you are not using ARC or the Project that is being converted not using ARC then the dealloc part or viewDidUnload method, where we generally make the objects nil and release.
Hope it helps you :)
There are some tool available. For example, http://kosmaczewski.net/projects/nib2objc/
I have different project set up for iPhone and iPAD and most of the file names in these two projects are same. Now i would like to merge these two into one and create a Universal build. Is there any tutorial or a better way to handle this without reworking on the complete code.
Please help. Thanks.
I already did that before. At that time, we did not have the choice to rename all the files and classes of one project. Objective-c does not have namespace, unfortunately.
Don't know how big is your project, but with rename/replace or re-factoring tool, you would be able to that without any (to much) pain.
If you use StoryBoard, then you can choose your project and when you choose Universal, you can set two different StoryBoards for iPhone and for iPad.
So you will have an application which initialize it according to iOS device.
And if you have same class names, I suggest you to change one of those with one character difference (eg. ViewController and PViewController (P for phone..)) and refactor all related class according to it.
Good luck!
I was wondering if somebody could explain in the details how I can localize an iOS app using only 1 storyboard. I know how to localize by creating several storyboards(one storyboard for each used language), however I'd like to find out another solution.
Thanks.
The tutorial on raywenderlich.com uses two forms of localization together. The reason is he also checks the storyboard when turning on localisation in image 3:
.
So then what?
NSLocalizedString is very useful, any text set programatically can (and should) be localised using this method. Ray's tutorial is still very useful.
However, it's not very desirable to create a clone of the storyboard(s) to do translation, it's just not very maintainable in the long run.
And what about storyboards?
The magic happens using the Base Localization feature. Base localization uses the generated objectId's to 'map' different languages to the storyboard.
Do note that this feature is only available using SDK 6.0 and above. Running the app on a lower iOS version will not cause any errors, it'll simply won't work.
Go to your project, and select Base Localization, then add any other language.
Open your storyboard file and check the new language as well. Note the icon is not a storyboard icon, but a simple text file icon. That's a good thing; it won't copy the whole storyboard this time :).
Note how there is now another file 'under' the storyboard. Xcode automatically generates a file for every language you select.
You can se Localization feature for this. You need to add the Localizable.strings file for each supported language and use it for locaization.
You need to use : NSLocalizedString() for fetcing data corresponding to each key.
Check this tutorial for details.
Ruby Motion just came out, and the screencast doesn't seem to say anything about whether or not you can use Interface Builder to build your interfaces and integrate them in your RubyMotion project. Is such a thing possible? Or do I really have code everything by hand, not to mention maintain to different pieces of code for iPhone/iPad?
My rep isn't high enough to create a rubymotion tag, so please help out if appropriate.
I'd just like to point out that RubyMotion 1.3 now support automatic compilation of .xib files that you put into the resources folder. So now the workflow becomes :
Create your .xib file using XCode (no need to create a project, just use File|New...|File) and save it into the resources folder. As there is no support for outlets yet, be careful to set the tag property for each control you want to use in your code (you'll find in the property sheet of each component under the "View" header).
RubyMotion will take care of compiling your .xib file into a .nib file, so enjoy :)
In your UIViewController derived class, load the nib using loadNibNamed:owner:options:, as shown below.
In viewDidLoad, fetch your various components using viewWithTag: and add events handlers using addTarget:action:forControlEvents:,as show below.
As a bonus, next time you want to edit your xib, just do open resources/MyView.xib, it will only launch the good parts of XCode.
class CalculatorViewController < UIViewController
def loadView
views = NSBundle.mainBundle.loadNibNamed "Keyboard", owner:self, options:nil
self.view = views[0]
end
def viewDidLoad
button = view.viewWithTag 1
button.addTarget self, action:'buttonTapped:', forControlEvents:UIControlEventTouchUpInside
end
def buttonTapped(button)
# ...
end
end
Yes you can use Interface Builder in RubyMotion.
.xib files that are located in the resources directory are automatically compiled into .nib files and available to your project.
There is even a way to support outlets if you are so inclined :
https://github.com/yury/ib#readme
http://ianp.org/2012/05/07/rubymotion-and-interface-builder/
But if you really want to use IB then you could still probably use it to lay out your UI and just call
NSBundle.mainBundle.loadNibNamed(MY_NIB_NAME, owner:self, options:nil)
or similar. I don't think that RubyMotion does any name mangling so you can use your ruby classes in IB by explicitly setting them.
You can probably build the interface in IB and call the command-line tools to compile the XIB to a NIB.
However, you aren't going to be able to connect outlets or assign actions because IB can't parse the Ruby source files for the IBOutlet and IBAction tokens. Normally, the NIB loading code makes those connections for you after loading your NIB. You'll have to do that yourself, in code.
Of the two glaring weaknesses in RubyMotion, to me this is the worst. (The other is that lack of code completion will make writing to the Cocoa APIs really tedious.)
Cappuccino had the same problem. They developed a tool called XcodeCapp: https://github.com/cappuccino/cappuccino/tree/master/Tools/XcodeCapp
It creates "dummy" Obj-C files that you can connect your outlets and actions to in IB, automatically parses them in the background and enables you to use IB to layout your Cappuccino UIs.
It should be possible to take a similar approach with RubyMotion (if you really want to use IB).
Johannes
There is someone who has made that:
Here is a tutorial video: https://www.youtube.com/watch?v=cOapNvehbg4
And this is the website https://github.com/yury/ib
Extra-Tipp: To find wrappers for rubymotion check this source
http://rubymotion-wrappers.com/
Hope this helps