UISegmentedControl and localization - localization

I have a .xib file, with accompanying .strings files for different languages. The .xib file contains a label, and a UISegmentedControl.
When asking IB to localize the .xib file, I get the following .strings file:
"6.segmentTitles[0]" = "title1";
// ...More strings related to the segmented control...
"11.text" = "bla";
The 'bla' string belongs to the label.
Changing the 'bla` string is reflected in runtime, while changing the 'title1' string does not. Anyone knows why?

This question is not new, but as it is still without any answers I will add my solution as it may help others.
Generally, as it's mentioned above, it is an open bug that UISegmentedControl segment titles do not pick up localization strings.
- (void)viewDidLoad
{
...
// Locale will be picked automatically by NSBundle.
NSString *resourcePath =[[NSBundle mainBundle] pathForResource:#"MainStoryboard" ofType:#"strings"];
NSDictionary *resourceDict = [NSDictionary dictionaryWithContentsOfFile:resourcePath];
[self.segmentedControl setTitle:[resourceDict objectForKey:#"COo-BO-Ryl.segmentTitles[0]"] forSegmentAtIndex:0];
[self.segmentedControl setTitle:[resourceDict objectForKey:#"COo-BO-Ryl.segmentTitles[1]"] forSegmentAtIndex:1];
}
Where COo-BO-Ryl is the Object ID of segmentedControl.
Not very pretty, but does the job.

Related

iOS - How to set storyboard/interface builder preview Right to Left?

I am Developing an app which supports two languages i.e English and Arabic. I have done mostly all tasks i.e localisation within app + handle UI LTR (english language) , RTL (Arabic language).
Now I want to see preview for a UI in RTL in storyboard. By default it is LTR.
What I have done till now:
+(void)initialize {
NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];
NSArray* languages = [defs objectForKey:#"AppleLanguages"];
NSString *current = [languages objectAtIndex:0];
[self setLanguage:current];
}
+(void)setLanguage:(NSString *)l {
NSLog(#"\n\n\t ***** Hint Lang. selected by user: %# ****\n\n", l);
NSString *path = [[ NSBundle mainBundle ] pathForResource:l ofType:#"lproj" ];
bundle = [NSBundle bundleWithPath:path];
}
+(NSString *)get:(NSString *)key alter:(NSString *)alternate {
return [bundle localizedStringForKey:key value:alternate table:nil];;
}
For handle UI LTR OR RTL. For example when user selects english language I set UI as
[UIView appearance].semanticContentAttribute = UISemanticContentAttributeForceLeftToRight;
and when user selects Arabic language then I set UI as
[UIView appearance].semanticContentAttribute = UISemanticContentAttributeForceRightToLeft;
But I have to check every and run app iPhone UI screen whether it is fine or not for both LTR as well as RTL.
Is there any way by which we can see preview UI as RTL in storyboard (without to run in iPhone/simulator). Any suggestion will be Great!! Thanks in advance!!
I found a useful way to quickly preview the RTL layout while editing a storyboard/xib, but only for one view (like a UIView parent container). This is not a good approach, but can save you some time and does not need to run the app.
While on the editor, you can select any View and in the inspector change the Semantic property to Force Right to Left. This will preview your layout in RTL for the selected view.
This is just a quick way to test a single container or control, the major drawback is that to preview the whole layout in RTL (including child views) you would need to go one by one and change this property.

Unable to set custom font for the UILabel in XCode

I am unable to set custom font for the UILabel in XCode.
This is what I've tried:
Download "JennaSue" font -- http://www.dafont.com/jenna-sue.font
Open "app-info.plist" under "Supporting Files" folder
Add new row in the list with key "Fonts provided by application"
In this array add "JennaSue.ttf"
Use it in the code like this:
self.someLabel.font = [UIFont fontWithName:#"JennaSue" size:14];
And nothing happens -- the default font is visible.
Why? What am I doing wrong? How can I fix it?
Be sure your font is in Bundle Resources. For some reason Xcode it is not importing custom font properly most of the time:
I've got the font working:
Example code: here
Go to your project's info.plist file,
Right click and select Add row,
Type Fonts provided by application in the new row,
Type in the desired font name as items for this key.
Drag and drop the font file into the project,
Apply it to the text you want:
someLabel.font = [UIFont fontWithName:#"JennaSue" size: 12.0];
I think you've missed step 5 up there.
Update: When doing step 5, remember to check the marks for copying the actual file into project directory:
Remember to clean your project by pressing "command+alt+shift+K" (IRRC!)
And then go to your
and then go to your project's Build Phases, and make sure you can see your .ttf file file among the resource files:
P.S. I'm not on my Mac at the moment, so I used screenshots from this tutorial. That's why I grayed out the unnecessary lines for your issue.
Check this code:
NSArray *names = [UIFont familyNames];
NSLog(#"Font FamilyNames : ");
for (NSString *name in names) {
NSLog(#"Font Family: %#",name);
NSArray *fontFaces = [UIFont fontNamesForFamilyName:name];
for (NSString *fname in fontFaces) {
NSLog(#" %#",fname);
}
}
self.someLabel.font = [UIFont fontWithName:#"use correct name" size:self.someLabel.font.pointSize];
and use the same name printed with NSLog.
After adding custom font to Xcode don't forget to add font to plist.
Project settings > Info > Custom IOS target properties
Add property Fonts provided by application and type your custom font(filename of font file).
Then you can use that code example
self.someLabel.font = [UIFont fontWithName:#"JennaSue" size:14];
Notice: make sure that you use right font name in code. To do that you should add this font to your Mac's font book, open font book, choose that font and check the right name font.
Hope this helps
self.someLabel.font = [UIFont fontWithName:#"JennaSue.ttf" size:self.someLabel.font.pointSize];
i used following code and it's done
UILabel * lblTest = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 200, 100)];
lblTest.font = [UIFont fontWithName:#"JennaSue" size:25.0];
lblTest.text = #"Hello World";
[self.view addSubview:lblTest];
and if still not working looking at your system font book and search that font and That Font you have to use to get it work
also try this lblTest.font = [UIFont fontWithName:#"Jenna Sue" size:25.0];
The font could be corrupted or something. I tried the solutions provided by Gabriel.Massana & Neeku and it worked on some fonts. Try adding the font to your Mac. If it showed verification problem, most probably it's not gonna work in your app. Hope this helps
is the file visible in Compile Source now…if yes then you may have the font name wrong..sometimes the font names are different then their file name…try running a
for (NSString *familyName in [UIFont familyNames])
{
for (NSString *fontName in [UIFont fontNamesForFamilyName:familyName])
{
NSLog(#"%#", fontName);
}
}
this lines of code..you will be able to see the actual name of the font and use that name instead
Here is #Ritu's answer in Swift 2. Just put this in your AppDelegate, or in viewDidLoad method of your View Controller:
let names = UIFont.familyNames()
for name in names {
print("Font Family: \(name)")
let fontFaces = UIFont.fontNamesForFamilyName(name)
for fname in fontFaces {
print(" \(fname)")
}
}
You will have all your font names in console log, just copy and paste the one you need in your code.

Localizing attributed UITextView from storyboard

I am using the storyboard and have a view where I have subclassed some UITextViews.
My problem is that I am using ibtool --generate-strings-file to extract strings from the storyboard for localization and afterwards use ibtool -write on another storyboard file to apply the translated strings.
When I use ibtool any UITextViews that have attributed text is ignored by the ibtool --generate-strings-file command and omitted from the resulting strings file.
Is it possible to extract attributed text from a storyboard for localization?
on Xcode 6.1, the best way is to copy the attributed text of a text view into a “BASE” RTF text ( using TextEdit for example or directly from XCode > New File > ressources > RTF ).
Going through the TextEdit way, you need to import your text into your project. Obviously, if you have done it through Xcode, nothing to import.
then just you use the utilies panel to find the “localize..." button which will do it's deed for you.
to import the correct version just do ( in viewWillAppear for ex. ),
NSURL *url = [[NSBundle mainBundle] URLForResource:[fileName stringByDeletingPathExtension] withExtension:[fileName pathExtension]];
NSError *error;
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithFileURL:url
options:#{NSDocumentTypeDocumentAttribute:NSRTFTextDocumentType}
documentAttributes:nil
error:&error];
[_originalMessage setAttributedText:attributedString];
Update for Swift 4:
var attrString: NSAttributedString?
let fileUrl: URL = Bundle.main.url(forResource: "mytextfile", withExtension: ".rtf")!
do {
attrString = try NSAttributedString(url: fileUrl, options: [.documentType:NSAttributedString.DocumentType.rtf], documentAttributes: nil)
} catch {
// Somebody do something!!
}
I ended up concluding that it couldn't be done using ibtool in the present version.
Instead I let the Textview be a plain text view and, using my subclass, parsed its text property so I could make a NSMutableAttributedString and set the needed properties.
That enabled me to use ibtool to extract the strings and still have an attributed textview.
It wouldn't make sense to localize attributed text from the storyboard as you would need to know where to apply the attributes after the translation. The word order might have changed and where you would have specified some blue bold text for instance might no longer make sense.
You can of course still do it via code where you can split up your string in multiple ones and localize them individually. Then you can specify setAttributes:range: so that you know that the right attributes will always be applied on the right range of the string.
Here's a workaround which I find quite useful: just create a ViewController with the translated TextView. In details (here I just translate the attributed text into english):
1) Crete a new Controller with "New File" -> "UIViewController with Xib". Name it "AttributedTranslated" and fill it with just a TextView with the attributed text being translated, using Interface Builder.
2) In your main controller .m file, write down the following method:
- (BOOL)isEng {
return [[[NSLocale preferredLanguages] objectAtIndex:0] isEqualToString:#"en"];
}
3) Define an "AttributedTranslated" object and a View in your .h file
IBOutlet UIView *attrView;
AttributedTranslated *attr;
4) On the xib file (or storyboard) of your main controller, create a View containing just the attributed textView (in the original language) and link it to "attrView".
5) On you viewDidLoad do something like the following:
if ([self isEng]) {
desc = [[Description alloc] init];
[attrView addSubview:attr.view];
}
Maybe it's not the best way to do it, but it does allow one to translate the attributed text in Interface Builder, easily!

Program crashes when adding NSMutableArray of strings to a UILabel

When I add this array of strings to the summaryText UILabel it crashes. Please let me know how to fix this.
NSMutableArray *arr = [[NSMutableArray alloc]init];
arr = [Singleton getArray];
NSString *str = [arr componentsJoinedByString:#"\n"];
summaryText.text = str;
This is what was brought up when i command clicked summaryText
#implementation TotalViewController
#synthesize tax,taxLabel,total,totalLabel,final,finalLabel,fiveLabel,threeLabel,twoLabel,five,three,two, points, pointsLabel,summaryText;
I had suggested initWithArray, but not clear why you don't replace entire above snippet with:
summaryText.text = [[Singleton getArray] componentsJoinedByString:#"\n"];
But as others pointed out, your crash isn't here, this just simplifies your code. The problem has to rest elsewhere, probably related to the definition/creation of summaryText. Hard to say without seeing crash log or more code.
Update:
You said that you created this control in Interface Builder. You might want to double check your "connections inspector" for that control and make sure your outlet is set up correctly. This sounds a lot like a control that hasn't been set up correctly in Interface Builder. Or you can look at you .h file in Xcode and it will tell you if it's successfully linked to a control in Interface Builder. You'll see a little "circle" to the left of the source code, a solid dot in the circle means that your outlet is hooked up correctly, and empty circle means that it's not (e.g. in this example below, contactName, contactAddress, and contactPhone are all linked up correctly, but myLabel is not):

Is there an option to implicitly localise labels in Interfacebuilder

Somewhere in a blog post I stumbled upon a strings file which looked like this:
// de.lproj/Localizable.strings
"This is the title" = "Das ist der Titel"
To me this looked like the actual labels in Interface builder were processed by the compiler so that no explicit translations using NSLocalizedString(#"SOME_IDENTIFIER", #""); would be necessary any more.
My question now, is whether there is some kind of shortcut or do I need to localise all my individual labels on my view e.g. in the awakeFromNib method.
I have figured out a way to semi-automate the process so that I don't have to do this:
label1.text = NSLocalizedString(#"label1_key", #"");
label2.text = NSLocalizedString(#"label2_key", #"");
....
labeln.text = NSLocalizedString(#"labeln_key", #"");
So for all labels which should be localised I set their text to __KeyForLabelX in IB. Then in the viewWillAppear method of the viewcontroller I loop through the items on the view and set the text to the localized value:
for (UIView *view in self.view){
if([view isMemberOfClass:[UILabel class]]){
UILabel *l = (UILabel *)view;
BOOL shouldTranslate = [l.text rangeOfString:#"__"].location != NSNotFound;
NSString *key = [l.text stringByReplacingOccurrencesOfString:#"__" withString:#"TranslationPrefix"];
if (shouldTranslate){
l.text = NSLocalizedString(key, #"");
}
}
}
My .strings file then look like this:
"TranslationPrefixKeyForLabelX" = "Translation of Label X";
Update: To further adapt the mechanism you could also check for other UIViews like UIButtons, UITextFields (including prompt text) etc.

Resources