I need to localiza a in development app for English & Spanish.
Despite the fact I follow the Apple way of use NSLocalizedString & create nibs for both, I already lost the track of the new string that need to get localized and found with surprise that I need to redo the nibs in spanish when I change the master.
(Just like this http://www.gigliwood.com/weblog/Cocoa/A_Great_Need_for_Be.html)
I wonder if exist a better/alternative/more automated way.
I know the use of gettext & poedit and wonder if something like that can be used.
Or if exist some script or tool for this.
There really isn't an easy fix here. NIBs need to be individually laid out for every language. To some extent, this improves overall user interface, because different languages actually often need different layout to look their best. Russian and German are much "larger" languages in screen real estate than English. Chinese can often be much smaller and a different layout looks better with Chinese characters. Arabic and Hebrew are right-to-left and may need radical changes to layout. Automated layout is easy, but achieves this by being varying levels of ugly in all languages. When given the choice between easy for the developer and ugly vs. difficult for the developer and beautiful, Apple almost always chooses the latter. That said, Apple has still not made it nearly as easy as they could.
So the first lesson here is to keep your NIBs simple. This is easier on iPhone than on Mac because iPhone doesn't have bindings and iPhone NIBs are generally simpler anyway. You can also use text injection for NIBs that have very small amounts of text (like a title). "Text injection" is a fancy way of saying "use an outlet for the label and set it to the localized text when you load the view."
ibtool is able to pull strings out of NIBs and also shove them back in, which can be helpful. I've used iLocalize, which is helpful for working with contract localizers, but doesn't really help with the problem you're talking about.
I tried getting rid of NIBs and just using code, thinking it would make things easier, but it really didn't. It was easier to lay out each language in the NIB than to come up with layout logic that would look good in all languages (see first paragraph). Text injection was only useful in a handful of places. If you can split your NIBs up into ones that need to be localized and those that don't, that can be helpful. On iPhone, I found that less than half of my NIBs actually had text or localized images in them.
Of course you should read Internationalization Programming Topics, but I'm sorry to say there really is no easy answer to your problem. Shipping products localized in 19 languages, I feel your pain.
Sometimes NiBs need to be laid out for each language, but most of the time they do not have to be re-laid out for each language.
If you used ibtool to generate the strings from the nibs
ibtool --generate-strings-file
You can import them into new nibs for each language.
ibtool --import-strings-file
These are command line tools so they are scriptable. Take a look at 'man ibtool'
What i do is that i create IBOutlets for all text ui in my nib file (UILabel, UITextField, UITextView, etc) and i assign its text/placeHolder properties to the desired NSLocalizaedString programatically.
Given that i have provided the translations of a particular string in different langs, the translated version of the text will appear in the nib file when the iPhone locale changes.
Hope others find this useful
Related
We are a team, creating a very big application for iPad that serves as an eReader for unprivileged children. The app is built halfway and I thought we should take a step backwards and review the whole design of the application. The application we are building should be very, very compliant with the current software development architecture practices for iOS. I have the explanation along with the questions below:
The application right now, has about 50 views (and increasing) and most of the Top-Level views are in the Storyboard (a single storyboard, that is) and the others are in XIBs (for the sub-views, reusable item renderers etc).
Is this approach alright?
Should XIBs be completely omitted for the modern iOS applications?
Should the storyboard be right the way it is or should it be broken down into sub-storyboards? If they should be, how should the exact process of decomposing the storyboard be done? How would the modules be determined?
If you have some tips to manage the application in the right way or some rule of thumbs to assist in a streamlined and modular application, please mention it in your comments.
I'm sorry for the long text up there and I thank you for reading.
This is a bit of a subjective one, but in my opinion it is still valid, and desirable, to use Xibs alongside storyboards. The idea of storyboards is nice, but with the current implementation they are definitely lacking some functionality, the most glaring of which is view reuse. I have worked on a few large projects recently, and storyboards always start out nice, but sooner or later you find yourself copy and pasting table cells, and then controllers, and then you have to change things in multiple places with each update, which is totally unmaintainable. So yes, definitely stick with the Xib files for reusable views.
I am less keen on the idea of multiple storyboards however. While this is easy enough to achieve technically, for me it invalidates the purpose of storyboards entirely. Their only use is as a (relatively) clear overview of the flow of controllers through the application. They add a few small conveniences, but in general I find they often create more code than they save, and create some odd code patterns (eg prepareForSegue:, having to temporarily store ivars when you want to segue to a controller in code that needs properties setting). As you say, how do you split up the storyboards into sub-storyboards? I can only think that whatever partitioning scheme you choose would be somewhat arbitrary, and liable to change at a later date when the app structure changes, which would be no fun at all. Maybe if your application has distinct modes of operation it makes sense to split up the storyboard, but I don't think this would apply to most apps.
So, IMO, single storyboard but use Xibs for reusable views.
I'd like different words in a UILabel to be different colors. Does this mean each word will need to be a different UILabel? I'm guessing yes, though sure would be nice to just put color codes in the label somehow, you know? I guess I'm a bit spoiled by text markup in HTML.
There is no proper UIRichTextView in iOS. It's high on my wish-list for iOS 6 (and there's some reason to believe we may get it then due to the release of Pages).
Your options are to use multiple UILabel views, NSString UIKit Additions, Core Text, UIWebView, or one of a few third-party frameworks such as:
NSAttributedString-Additions-for-HTML
CoreTextWrapper
OHAttributedLabel
OmniUI
All of the current solutions have different problems. The most common problem is that it's hard to get select and copy functionality to work with rich text unless you use a web view. Web views are incredibly annoying because they're asynchronous and you have to do a lot of your interactions in JavaScript.
I wish there were a better answer.
(Obligatory shilling: This topic is covered in depth in Chapter 18 of iOS 5 Programming Pushing the Limits.)
UILabel doesn't support segmented formatting (the entire thing can only have one format).
Have a look at OHAttributedLabel, which does what you want.
As far as I'm aware you'd need to have separate labels for each different coloured word. Depending what you're trying to do you may be able to make use of myLabel.textColor to change the colour of the periodically or on events etc.
I recently worked in a ipad project. I find no nib files in the entire project. Is there a specific reason for such standards? I find it really difficult to follow that kind of project.
I'm not sure I would consider this a "standard". Some devs just prefer to code all their views as opposed to using Interface Builder. The initial releases of IB were a bit flaky and people avoided it due to this. I don't really see any reason to avoid using IB nowadays unless you are doing a completely custom user interface or a game. In the case of a custom UI, it might be easier to build it up in code compared to trying to bend the IB elements to your will.
a nib, particularly if localized, breaks DRY.
initialization is beyond your control when using a nib.
code and program reuse is more difficult. consider libraries and multiple apps.
it's easier to manage/update an implementation from fewer locations/files/resources. let's say you want to change the app's color theme... very painful if you have to modify all the app's nibs, as opposed to changing the definition of a function. also pretty close to useless if you layout the groundwork at the source level for color themes in addition to using nibs -- at that point, you're already setting up your views programmatically.
improved performance (where that's important).
program security. IB used to support plugins/addons in osx... those were just removed.
frameworks are not an option in iOS. nibs can't be shared via libraries as easily as compiled programs.
for long term and large scale development, it makes a lot of sense to write it programmatically, whereas IB's really handy for prototyping.
Agreed, IB is pretty stable and a lot more featured that it used to be. Although iirc using IB does add more weight to the project than if it was all done via code.
Aside from the WYSIWYG editor, what are the advantages of using XIB/NIB files over defining the layout in code in iPhone/iPad/iOS?
While I don't find XIB files much useful, many iOS developers do, which makes me suspect I might not know their benefits or how to use them properly.
Easier maintenance. More often than not, clients require last minute changes like changing the logo or changing colors or realigning something or some such. Much easier to change it in a xib file and see/show the results immediately
Decoupling. It forces you to write nicely decoupled code right from the offset, which again means easier maintenance.
Defining things in Interface Builder makes them much easier to adjust later. Also, doing interface elements in code can lead to a lot of code bloat, for setting things like exact placement, font, color, etc.
The main advantage using code directly gives you is speed. But it's usually better to start in IB and then see what might need speeding up.
Table cells are one of the main areas where you might consider drawing elements in code for speed.
Personnaly, I'm using XIB to see graphically my I'm doing so I don't have to run, check the look, change a bit the color, run the app, check... It allows me to get a better design. If you work with designer that gives you photoshop design, it will not be useful for you.
Second thing : when you start to really handle Xib, it's much faster than doing it with code (but it takes time and training for TableView and tableView cell for example)
Are there any good reasons why I should not use XIB / NIB files with an highly customized UI and extensive animations and super low memory footprint needs?
As a beginner I started with XIB. Then I figured out I couldn't do just about everything in them. It started to get really hard to customize things the way I wanted them to be. So at the end, I threw all my XIBs away and did it all programmatically.
So when someone asks me if XIB is good, I generally say: Yeah, if you want to make crappy boring interfaces and don't care too much about performance, go ahead. But what else could be a reason not to use XIB?
Am I the only iPhone developer who prefers doing everything programmatically for this reasons?
I think that Interface Builder is one of the biggest assets of Mac (and by extension, iPhone) software development. GUIs are visual; why not create them using a visual interface? IB is flexible enough that you can lay out an interface using its "generic" components, and then subclass them where necessary. Sure, if you have a unique interface you're going to have to subclass a view class and perform custom drawing, but you can also lay out your interface in IB and then easily use the inspector to switch the class to your custom subclass.
Honestly I think it's a spectrum of convenience. If you are comfortable writing everything in code then go for it. If you design your project well then it should be about the same amount of work creating new windows, etc. But I know that a lot of people aren't as comfortable with the GUI world so nib/xibs work well there.
I honestly find myself using XIBs as a base quite often and editing them with code to get the specific look I want. Personal preference.
For a specific con on that point, views can be difficult to configure after loading them from a xib. When you have conflicting settings between IB and code that can be nasty to troubleshoot.
Here's a question for the list. What is the performance hit to using a xib? I thought they were a plus because they don't get loaded into memory until you need them. That said, that load time is longer which will slow your program down. Thoughts?
One thing I found better about code is for the event connections on controls, when you search for uses of a method (message) you find them if they are coded and you don't find them if they were set in IB.
On the other hand laying out objects on a view is much easier in IB where you can see their size and positions. When you do that in code you have to guess at the size and origin settings and then run it and make adjustments, then run it again to see what it looks like.
When your application has some kind of "standard" views, go with the XIB. If you need real customization, depending on external content (XML...) do it programatically.
I started using XIBs and now it's all code, I find myself more comfortable this way. I had real problems with XIBs, and now writing the interfaces all in code really saves me time.
I save tons of time when dealing with UIControllers (UITabBarControllers, UINavigationControllers etc.) in the start up phase where all the navigation stuff is hooked up.
I just build X viewControllers with a accompanying XIB, throw in the stuff needed in IB, labels, images etc. This means that for almost any sort of app you can have a proof of concept up in a few hours. This is enough to justify spending some time learning the ins and outs of IB. Especially on the iPhone where you can have a ton of good UI ideas, but they all fail when they move from the Simulator to an actual device.
The best thing, in my mind, is to balance it out, if you find yourself using a lot of time doing the "change the frame 3 px -> compile -> ahh.. needs two pixels more -> change 2 px - compile -> ahh.. 1 more px" for something that could be done in IB, you will seriously start to waste time.
I start as above, but afterwards I often throw the XIBs away for custom stuff. The trick is to not spend hours on implementing versions of custom stuff in code over and over again, but figure out how it should be and do the custom stuff once:)
The XML content of a nib file is very complicated. This makes it extremely difficult to review changes or fix merge conflicts with a version control system like Git.
Interface Builder is a nice idea, but Bret Victor, in his talk "Inventing on Principle" and his essay "Learnable Programming," implicitly challenges Apple to build an even better IDE.
One idea, based on Bret Victor's principle: What if I could select a "Move Tool" in the iOS Simulator app that let me move a button in my app and then the frame code changed in the implementation (.m) file? This would be much better.