Posted by Ricibald on 3rd June 2011
Scenario:
I want to localize my app AllSync but I was taken by a little frustration.
Following this good guide you can see that there are two main way to localize your iOS (iPhone/iPad) app:
- localize strings using Localizable.strings
- localize single nib file creating one version for each
The second point is very frustrating for three reasons:
- you have to mantain updated all version of your nib localized files
- there are specialized sites like icanlocalize that translates only your Localizable.string, not your nib files
- you have to take care about the resulting layout of single translation
The problem:
I want to localize my nib files in the same way of using Localizable.strings
A possible solution can be to externalize in code every text setting but is a tedious process and you can’t use the flexibility of xcode 4. The real solution I hope will be used by many of you is this:
The solution:
Create an extended version of iOS user control that automatically translates every single text
Simple to obtain: just see this extended UIButton
@interface UIButtonThemed : UIButton
@end
@implementation UIButtonThemed
- (id)initWithCoder:(NSCoder *)aDecoder {
if ((self = [super initWithCoder:aDecoder]))
{
self.titleLabel.adjustsFontSizeToFitWidth = YES;
NSString* text = NSLocalizedString(self.titleLabel.text, nil);
[self setTitle:text forState:UIControlStateNormal];
[self setTitle:text forState:UIControlStateHighlighted];
[self setTitle:text forState:UIControlStateDisabled];
[self setTitle:text forState:UIControlStateSelected];
}
return self;
}
@end
You can use it inside xcode 4 configuring the base class for your control:

Then you can see my italian Localizable.strings:
"Sync" = "Sincronizza";
"Settings" = "Impostazioni";
"Help" = "Guida";
"Share" = "Condividi";
"Rate us" = "Votaci";
"Follow us" = "Seguici";
And the corresponding result:
Posted in iphone, projects | 3 Comments »
Posted by Ricibald on 18th February 2008
In ASP.NET normalmente i comandi vengono assegnati tramite la creazione di un delegato che risponde all’evento “click” nel seguente modo:
void Page_Load(object sender, EventArgs e) {
ButtonStudente.Click += new EventHandler(this.Studente_Click);
}
void Studente_Click(object sender, EventArgs e) {
LabelMatricola.Text = this.Studente.Matricola;
}
Ma nel caso di molteplici pulsanti creati dinamicamente, allora “sarebbe” conveniente utilizzare le proprietà CommandName e CommandArgument, implementazioni “blande” del pattern Command in ASP.NET:
void Page_Load(object sender, EventArgs e) {
...
foreach(Studente s in studenti) {
Button buttonStudente = new Button();
buttonStudente.CommandName = "GetMatricola";
buttonStudente.CommandArgument = s.Matricola;
buttonStudente.Command += new CommandEventHandler(this.Studente_Click);
}
...
}
void Studente_Click(object sender, CommandEventArgs e) {
LabelMatricola.Text = (string)e.CommandArgument;
}
L’approccio è fattibile, ma fragile:
- parametri passati come oggetto generico da convertire
- se devo passare una lista di parametri?
- bisognerebbe creare la versione tipizzata della lista di argomenti
- possibili errori di cast
- possibili errori nella scansione del tipo di comando da trattare
- comportamento distribuito tra cicli e metodi con oggetti da convertire
Per situazioni come queste conviene invece utilizzare tutta la potenza dei delegati anonimi come segue:
void Page_Load(object sender, EventArgs e) {
...
foreach(Studente s in studenti) {
Button buttonStudente = new Button();
buttonStudente.Click += new EventHandler(delegate(object sender, EventArgs e) {
LabelMatricola.Text = s.Matricola;
});
}
...
}
L’approccio diventa elegante e facilmente comprensibile. Notare che la funzione viene solo dichiarata ed eseguita solo se il click avviene.
Posted in .net | 3 Comments »