Finalmente me estoy dando la vuelta para luchar con Auto Layout y no puedo entender cómo hacer que el soporte de derecha a izquierda (RTL) funcione de la manera que esperaría / querría …
He diseñado la vista en Interface Builder como se muestra:
Con la aplicación resultante funcionando como se esperaba al usar el inglés:
Sin embargo, al cambiar a un lenguaje RTL (en árabe en este caso), la vista entera se voltea (lo cual es genial) pero el texto de UILabel
todavía se alinea a la izquierda. Esperaría que esté alineado correctamente para mantenerlo en contra del UIImageView
.
Claramente me falta algo y / o esto no está cubierto por el diseño automático.
¿Se supone que debo configurar textAlignment
manualmente cuando uso un lenguaje RTL?
Desea NSTextAlignmentNatural
. Eso infiere la alineación de texto del lenguaje de la aplicación cargada ( no del script).
Para iOS 9 y posteriores (usando Xcode 7), puede configurar esto en el guión gráfico (elija la opción — Alineación). Si necesita segmentar lanzamientos anteriores, deberá crear una salida a la etiqueta y establecer la alineación en awakeFromNib
.
- (void)awakeFromNib { [[self label] setTextAlignment:NSTextAlignmentNatural]; }
Para mí, esas soluciones no ayudaron, y terminé haciendo algo bastante feo, pero es el único que hizo el truco para mí. Lo agregué como una categoría NSString
:
NSString + Extras.h:
#import @interface NSString (Extras) - (NSTextAlignment)naturalTextAligment; @end
NSString + Extras.m:
#import "NSString+Extras.h" @implementation NSString (Extras) - (NSTextAlignment)naturalTextAligment { NSArray *tagschemes = [NSArray arrayWithObjects:NSLinguisticTagSchemeLanguage, nil]; NSLinguisticTagger *tagger = [[NSLinguisticTagger alloc] initWithTagSchemes:tagschemes options:0]; [tagger setString:self]; NSString *language = [tagger tagAtIndex:0 scheme:NSLinguisticTagSchemeLanguage tokenRange:NULL sentenceRange:NULL]; if ([language rangeOfString:@"he"].location != NSNotFound || [language rangeOfString:@"ar"].location != NSNotFound) { return NSTextAlignmentRight; } else { return NSTextAlignmentLeft; } } @end
Para detectar el lenguaje, utilicé esta respuesta SO .
Creo que no desea usar alineación de texto en este caso, para una etiqueta.
Puedes dejar que el ancho sea determinado por intrinsicContentSize y eliminar cualquier restricción de ancho en la etiqueta. Conseguirá el efecto deseado del texto de la etiqueta alineado con la vista.
Para eje x, solo necesita esta restricción entre etiqueta e imagen: [imageview] – [label]
Esta es solo una restricción de espacio horizontal. Sin liderazgo ni seguimiento para supervisar.
Seguimiento de la respuesta de Ken
NSTextAlignmentNatural
es posible configurar textAlignment
a NSTextAlignmentNatural
en UILabel
, se generará una excepción:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'textAlignment does not accept NSTextAlignmentNatural'
Funciona al usar texto atribuido y esto se puede configurar en el Interface Builder como se muestra:
Sin embargo, parece que el texto atribuido no se recoge cuando se localiza el guión gráfico.
Para evitar esto, he dejado el UILabel
configurado como simple en Interface Builder y NSAttributedString
creado un NSAttributedString
con el texto de la etiqueta, establezco la alineación en la cadena atribuida y la asigno a la propiedad attributedText
la etiqueta:
-(void)viewDidLoad { [super viewDidLoad]; NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.alignment = NSTextAlignmentNatural; NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:self.lbl.text]; [string addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, string.length)]; self.lbl.attributedText = string; }
Esto funciona bien en este caso simple, pero puedo ver que se cae cuando necesitas un estilo de cuerda atribuido más complejo. Pero, obviamente, en ese caso, probablemente solo NSLocalizedString
usando NSLocalizedString
o equivalentes al crear NSAttributedString
.
@Aviel responde como una rápida extensión UILabel
//MARK: UILabel extension extension UILabel { func decideTextDirection () { let tagScheme = [NSLinguisticTagSchemeLanguage] let tagger = NSLinguisticTagger(tagSchemes: tagScheme, options: 0) tagger.string = self.text let lang = tagger.tagAtIndex(0, scheme: NSLinguisticTagSchemeLanguage, tokenRange: nil, sentenceRange: nil) if lang?.rangeOfString("he") != nil || lang?.rangeOfString("ar") != nil { self.textAlignment = NSTextAlignment.Right } else { self.textAlignment = NSTextAlignment.Left } } }
Cómo usarlo ?
label.text = "كتابة باللغة العربية" // Assign text label.decideTextDirection() // Decide direction
puede usar MyLayout para facilitar el soporte de RTL y LRT.
Esta función me ayudó
-(void)fnForWritingDirection:(UILabel*)label textFor:(NSString *)stringForText{ NSMutableAttributedString* attrStr = [[NSMutableAttributedString alloc] initWithString: [stringForText stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; [paragraphStyle setBaseWritingDirection:NSWritingDirectionRightToLeft]; [attrStr addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [attrStr length])]; label.attributedText=attrStr; }