He añadido una etiqueta en mi archivo nib, entonces su obligación de tener la parte superior izquierda de la alineación para que lable. Como me estoy dando de texto en tiempo de ejecución por lo que no es seguro que cuánto líneas.
Así que si el texto contiene sólo una sola línea, a continuación, aparece como vertical-centro alineados. Que la alineación no es coincidente con mi respectiva etiqueta en la frente de ella.

Por ejemplo:

Cómo definir la alineación a la izquierda para UILabel para la aplicación de iOS?

Que es de aspecto extraño 🙁

¿Hay alguna manera en la que puede establecer el texto de la etiqueta adecuada para la parte Superior Izquierda de la alineación?

InformationsquelleAutor Mrunal | 2011-08-25

18 Comentarios

  1. 64

    Es bastante fácil de hacer. Crear un UILabel sublcass con un verticalAlignment propiedad y reemplazar textRectForBounds:limitedToNumberOfLines para el retorno de los límites correctos para una parte superior, media o inferior de la alineación vertical. Aquí está el código:

    SOLabel.h

    #import <UIKit/UIKit.h>
    
    typedef enum
    {
        VerticalAlignmentTop = 0, //default
        VerticalAlignmentMiddle,
        VerticalAlignmentBottom,
    } VerticalAlignment;
    
    @interface SOLabel : UILabel
    
       @property (nonatomic, readwrite) VerticalAlignment verticalAlignment;
    
    @end

    SOLabel.m

    @implementation SOLabel
    -(id)initWithFrame:(CGRect)frame
    {
    self = [super initWithFrame:frame];
    if (!self) return nil;
    //set inital value via IVAR so the setter isn't called
    _verticalAlignment = VerticalAlignmentTop;
    return self;
    }
    -(VerticalAlignment) verticalAlignment
    {
    return _verticalAlignment;
    }
    -(void) setVerticalAlignment:(VerticalAlignment)value
    {
    _verticalAlignment = value;
    [self setNeedsDisplay];
    }
    //align text block according to vertical alignment settings
    -(CGRect)textRectForBounds:(CGRect)bounds 
    limitedToNumberOfLines:(NSInteger)numberOfLines
    {
    CGRect rect = [super textRectForBounds:bounds 
    limitedToNumberOfLines:numberOfLines];
    CGRect result;
    switch (_verticalAlignment)
    {
    case VerticalAlignmentTop:
    result = CGRectMake(bounds.origin.x, bounds.origin.y, 
    rect.size.width, rect.size.height);
    break;
    case VerticalAlignmentMiddle:
    result = CGRectMake(bounds.origin.x, 
    bounds.origin.y + (bounds.size.height - rect.size.height) / 2,
    rect.size.width, rect.size.height);
    break;
    case VerticalAlignmentBottom:
    result = CGRectMake(bounds.origin.x, 
    bounds.origin.y + (bounds.size.height - rect.size.height),
    rect.size.width, rect.size.height);
    break;
    default:
    result = bounds;
    break;
    }
    return result;
    }
    -(void)drawTextInRect:(CGRect)rect
    {
    CGRect r = [self textRectForBounds:rect 
    limitedToNumberOfLines:self.numberOfLines];
    [super drawTextInRect:r];
    }
    @end
    • También he intentado muchas otras soluciones de aquí ASÍ que antes de correr a través de este. Funcionó a la perfección! Tenga en cuenta que si usted está haciendo esto en el Guión gráfico, asegúrese de que establece la CustomClass atributo SOLabel (o lo que decida el nombre) en lugar de UILabel (en las Utilidades en el Inspector).
    • gracias por la auténtica solución.
    • Esto es muy útil, muchas gracias. No funciona para el centro o texto alineado a la derecha, pero el uso de bounds.size.width en lugar de rect.size.width en textRectForBounds:limitedToNumberOfLines: parece a arreglar eso.
    • Si has detectado ‘Rosca 1:EXC_BAD_ACCESS (Código 2, dirección=0x…)’ en iOS 9 Xcode 7, Basta con quitar el setter y getter -(VerticalAlignment) verticalAlignment; y -(void) setVerticalAlignment:(VerticalAlignment)funciones de valor, puesto que la variable es @de la propiedad. Se sintetiza y contiene los descriptores de acceso.
    • he de hacer algunas modificaciones a lo largo aquí en el método: «textRectForBounds» – resultado = CGRectMake(rect.origen.x, de límites.origen.y, rect.tamaño.ancho, rect.tamaño.altura); Para hacer mis trabajos rightAlignment UILable.
    • Funciona como por arte de magia 🙂

  2. 37

    He encontrado una solución mediante el diseño Automático en el Guión gráfico.

    1) Establecer el número de líneas a 0 y la alineación del texto a la Izquierda.

    Cómo definir la alineación a la izquierda para UILabel para la aplicación de iOS?

    2) Ajustar la altura de la restricción.

    Cómo definir la alineación a la izquierda para UILabel para la aplicación de iOS?

    3) La altura de la Restricción debe estar en Relación de Menor o Igual

    Cómo definir la alineación a la izquierda para UILabel para la aplicación de iOS?

    4)

       override func viewWillLayoutSubviews() {
    sampleLabel.sizeToFit()
    }

    Me dieron el resultado de la siguiente manera :

    Cómo definir la alineación a la izquierda para UILabel para la aplicación de iOS?

    • Funciona como un encanto, incluso en un UITableViewCell con la reutilización.
    • Super simle y fácil! Gracias
    • Se colocan los viewWillLayoutSubviews en el controlador o la celda de archivo? Si el controlador, ¿cómo acceder a la UILabel de la célula?
    • ¿Dónde se coloca el paso 4? Como un usuario nuevo, yo estaba emocionado de tener un carácter puramente interfaz de usuario de la solución, entonces, que el código que sale de la nada y no nos dijo donde ponerlo
    • Ya sea en SampleClass.swift o SampleTableViewCell.swift
    • Esta debe ser la Solución. Funciona perfectamente, ningún hack o subclases necesario.

  3. 37

    La SOLabel funciona para mí.

    Swift 1:

    class UIVerticalAlignLabel: UILabel {
    enum VerticalAlignment : Int {
    case VerticalAlignmentTop = 0
    case VerticalAlignmentMiddle = 1
    case VerticalAlignmentBottom = 2
    }
    var verticalAlignment : VerticalAlignment = .VerticalAlignmentTop {
    didSet {
    setNeedsDisplay()
    }
    }
    required init(coder aDecoder: NSCoder){
    super.init(coder: aDecoder)
    }
    override func textRectForBounds(bounds: CGRect, limitedToNumberOfLines: Int) -> CGRect {
    let rect = super.textRectForBounds(bounds, limitedToNumberOfLines: limitedToNumberOfLines)
    switch(verticalAlignment) {
    case .VerticalAlignmentTop:
    return CGRectMake(bounds.origin.x, bounds.origin.y, rect.size.width, rect.size.height)
    case .VerticalAlignmentMiddle:
    return CGRectMake(bounds.origin.x, bounds.origin.y + (bounds.size.height - rect.size.height) / 2, rect.size.width, rect.size.height)
    case .VerticalAlignmentBottom:
    return CGRectMake(bounds.origin.x, bounds.origin.y + (bounds.size.height - rect.size.height), rect.size.width, rect.size.height)
    default:
    return bounds
    }
    }
    override func drawTextInRect(rect: CGRect) {
    let r = self.textRectForBounds(rect, limitedToNumberOfLines: self.numberOfLines)
    super.drawTextInRect(r)
    }
    }

    Swift 3:

    Esta versión ha sido actualizada de la original para permitir el soporte para idiomas RTL:

    public class VerticalAlignLabel: UILabel {
    enum VerticalAlignment {
    case top
    case middle
    case bottom
    }
    var verticalAlignment : VerticalAlignment = .top {
    didSet {
    setNeedsDisplay()
    }
    }
    override public func textRect(forBounds bounds: CGRect, limitedToNumberOfLines: Int) -> CGRect {
    let rect = super.textRect(forBounds: bounds, limitedToNumberOfLines: limitedToNumberOfLines)
    if UIView.userInterfaceLayoutDirection(for: .unspecified) == .rightToLeft {
    switch verticalAlignment {
    case .top:
    return CGRect(x: self.bounds.size.width - rect.size.width, y: bounds.origin.y, width: rect.size.width, height: rect.size.height)
    case .middle:
    return CGRect(x: self.bounds.size.width - rect.size.width, y: bounds.origin.y + (bounds.size.height - rect.size.height) / 2, width: rect.size.width, height: rect.size.height)
    case .bottom:
    return CGRect(x: self.bounds.size.width - rect.size.width, y: bounds.origin.y + (bounds.size.height - rect.size.height), width: rect.size.width, height: rect.size.height)
    }
    } else {
    switch verticalAlignment {
    case .top:
    return CGRect(x: bounds.origin.x, y: bounds.origin.y, width: rect.size.width, height: rect.size.height)
    case .middle:
    return CGRect(x: bounds.origin.x, y: bounds.origin.y + (bounds.size.height - rect.size.height) / 2, width: rect.size.width, height: rect.size.height)
    case .bottom:
    return CGRect(x: bounds.origin.x, y: bounds.origin.y + (bounds.size.height - rect.size.height), width: rect.size.width, height: rect.size.height)
    }
    }
    }
    override public func drawText(in rect: CGRect) {
    let r = self.textRect(forBounds: rect, limitedToNumberOfLines: self.numberOfLines)
    super.drawText(in: r)
    }
    }
    • Gracias! Esto funciona para mí.
    • Si intento crear una etiqueta utilizando el siguiente código: var myLabel = VerticalAlignLabel() me sale una «Falta el argumento para el parámetro ‘programador’ en llamar». ¿Cómo puedo crear una etiqueta utilizando este VerticalAlignLabel subclase?
    • Pruebe el Swift versión 3 ahora – yo tenía un método init que no es necesario.
    • muy bonito, gracias!
    • Funcionó a la perfección. Gracias !!
  4. 12

    En el código

    label.text = @"some text";
    [label sizeToFit];

    Ten en cuenta que si el uso que en las celdas de la tabla o de otra índole que sea reciclado con diferentes datos, usted necesita para almacenar la trama original en algún lugar y se restablecerá antes de llamar a sizeToFit.

    • va a trabajar, mientras que el uso de textAlignment ‘Derecho’?
    • Me gustaría recomendar la realidad y dejar todo para el diseño Automático en este punto. Esto no es necesario ya.
  5. 7

    He encontrado otra solución para el mismo problema. He utilizado UITextView en lugar de UILabel y cambió editable() función false.

    • Trabajó para mí! Buena captura
    • Este es un tonto hack en el mejor de los engañosa para el futuro de los desarrolladores en el peor…
    • ¿Por qué es este un tonto hack? Parece una solución decente, hay otros problemas con los que además de no ser una respuesta directa a la pregunta?
    • No es apropiado, porque usted no está utilizando el componente de interfaz de usuario para el trabajo. NO debe ser un compromiso para algo tan simple como la alineación vertical. Necesidad de utilizar el componente adecuado para el trabajo. Cualquier otra cosa es un hack…
  6. 6

    Yo también tenía este problema, pero lo que me encontré fue el orden en el que se establece la UILabel las propiedades y métodos de los asuntos!

    Si usted llama [label sizeToFit] antes de label.font = [UIFont fontWithName:@"Helvetica" size:14];, a continuación, el texto no se alinea con la parte superior, pero si el intercambio de todo, a continuación se hace!

    También me di cuenta de que se ajuste el texto por primera vez se hace una diferencia demasiado.

    Espero que esto ayude.

    • Gran. sizeToFit() debe ser llamado en el último.
  7. 5

    En mi caso, fue bottom space problema de limitación. Me había puesto a = 16.

    Cuando me puse a bottom to >= 16, este problema se solucionó.

    También, si usted tiene alguna restricción de altura en la etiqueta, a continuación, usted tiene que quitar.

    Aquí está mi sello de restricciones de la vista en el tamaño del inspector:

    Cómo definir la alineación a la izquierda para UILabel para la aplicación de iOS?

    • Yo no tengo las opciones de Restricción al seleccionar una etiqueta.
  8. 4

    Cuando usted está usando la interface builder, establece las restricciones para la etiqueta (asegúrese de ajustar la altura y la anchura así). A continuación, en el Tamaño de Inspector, compruebe la altura de la etiqueta. No tendrá que leer >= en lugar de =. A continuación, en la aplicación para que el controlador de vista, establecer el número de líneas a 0 (también se puede hacer en IB) y el conjunto de la etiqueta [etiqueta sizeToFit]; y como el texto de las ganancias de la longitud, la etiqueta va a crecer en altura y de mantener el texto en la parte superior izquierda.

    • trabajó para mí y me salvó un montón de tiempo. thx. 🙂
    • gran respuesta simple. Thx!
  9. 3

    Solución con SoLabel funciona , muchas Gracias.

    Fuelle he añadido monotouch versión:

        public class UICustomLabel : UILabel
    {
    private UITextVerticalAlignment _textVerticalAlignment;
    public UICustomLabel()
    {
    TextVerticalAlignment = UITextVerticalAlignment.Top;
    }
    public UITextVerticalAlignment TextVerticalAlignment
    {
    get
    {
    return _textVerticalAlignment;
    }
    set
    {
    _textVerticalAlignment = value;
    SetNeedsDisplay();
    }
    }
    public override void DrawText(RectangleF rect)
    {
    var bound = TextRectForBounds(rect, Lines);
    base.DrawText(bound);
    }
    public override RectangleF TextRectForBounds(RectangleF bounds, int numberOfLines)
    {
    var rect = base.TextRectForBounds(bounds, numberOfLines);
    RectangleF resultRect;
    switch (TextVerticalAlignment)
    {
    case UITextVerticalAlignment.Top:
    resultRect = new RectangleF(bounds.X, bounds.Y, rect.Size.Width, rect.Size.Height);
    break;
    case UITextVerticalAlignment.Middle:
    resultRect = new RectangleF(bounds.X,
    bounds.Y + (bounds.Size.Height - rect.Size.Height)/2,
    rect.Size.Width, rect.Size.Height);
    break;
    case UITextVerticalAlignment.Bottom:
    resultRect = new RectangleF(bounds.X,
    bounds.Y + (bounds.Size.Height - rect.Size.Height),
    rect.Size.Width, rect.Size.Height);
    break;
    default:
    resultRect = bounds;
    break;
    }
    return resultRect;
    }
    }
    public enum UITextVerticalAlignment
    {
    Top = 0, //default
    Middle,
    Bottom
    }
  10. 3

    La más simple y sencilla es la de insertar la Etiqueta en StackView y configuración de StackView del Eje Horizontal, la Alineación de la parte Superior en el Atributo Inspector de Storyboard como se muestra aquí.

  11. 2

    Si lo que necesita es no editable texto que por defecto se inicia en la esquina superior izquierda, puede simplemente utilizar una Vista de Texto en lugar de una etiqueta y, a continuación, establezca su estado no editables, como este:

    textview.isEditable = false

    Manera más fácil de jugar con las etiquetas…

    Saludos!

  12. 2

    Edificio en la parte superior de totiG impresionante respuesta, he creado una IBDesignable de clase que hace que sea muy fácil de personalizar un UILabel la alineación vertical a la derecha del Guión. Sólo asegúrese de que usted establezca su UILabel de la clase a ‘VerticalAlignLabel’ del Guión de la identidad del inspector. Si la alineación vertical no surte efecto, ir a Editor->la Actualización de Todos los puntos de vista que debe hacer el truco.

    Cómo funciona:
    Una vez establecido el UILabel la clase correctamente, el guión gráfico debe mostrar un campo de entrada que toma un entero (alineación de código).

    Actualización: he añadido soporte para centrados en las etiquetas de los ~Sev


    Introduzca 0 para la parte Superior de la Alineación

    Introduzca 1 para el Medio de la Alineación

    Introduzca 2 para la parte Inferior de la Alineación

    HTML:

        @IBDesignable class VerticalAlignLabel: UILabel {
    @IBInspectable var alignmentCode: Int = 0 {
    didSet {
    applyAlignmentCode()
    }
    }
    func applyAlignmentCode() {
    switch alignmentCode {
    case 0:
    verticalAlignment = .top
    case 1:
    verticalAlignment = .topcenter
    case 2:
    verticalAlignment = .middle
    case 3:
    verticalAlignment = .bottom
    default:
    break
    }
    }
    override func awakeFromNib() {
    super.awakeFromNib()
    self.applyAlignmentCode()
    }
    override func prepareForInterfaceBuilder() {
    super.prepareForInterfaceBuilder()
    self.applyAlignmentCode()
    }
    enum VerticalAlignment {
    case top
    case topcenter
    case middle
    case bottom
    }
    var verticalAlignment : VerticalAlignment = .top {
    didSet {
    setNeedsDisplay()
    }
    }
    override public func textRect(forBounds bounds: CGRect, limitedToNumberOfLines: Int) -> CGRect {
    let rect = super.textRect(forBounds: bounds, limitedToNumberOfLines: limitedToNumberOfLines)
    if #available(iOS 9.0, *) {
    if UIView.userInterfaceLayoutDirection(for: .unspecified) == .rightToLeft {
    switch verticalAlignment {
    case .top:
    return CGRect(x: self.bounds.size.width - rect.size.width, y: bounds.origin.y, width: rect.size.width, height: rect.size.height)
    case .topcenter:
    return CGRect(x: self.bounds.size.width - (rect.size.width /2), y: bounds.origin.y, width: rect.size.width, height: rect.size.height)
    case .middle:
    return CGRect(x: self.bounds.size.width - rect.size.width, y: bounds.origin.y + (bounds.size.height - rect.size.height) /2, width: rect.size.width, height: rect.size.height)
    case .bottom:
    return CGRect(x: self.bounds.size.width - rect.size.width, y: bounds.origin.y + (bounds.size.height - rect.size.height), width: rect.size.width, height: rect.size.height)
    }
    } else {
    switch verticalAlignment {
    case .top:
    return CGRect(x: bounds.origin.x, y: bounds.origin.y, width: rect.size.width, height: rect.size.height)
    case .topcenter:
    return CGRect(x: (self.bounds.size.width /2 ) - (rect.size.width /2), y: bounds.origin.y, width: rect.size.width, height: rect.size.height)
    case .middle:
    return CGRect(x: bounds.origin.x, y: bounds.origin.y + (bounds.size.height - rect.size.height) /2, width: rect.size.width, height: rect.size.height)
    case .bottom:
    return CGRect(x: bounds.origin.x, y: bounds.origin.y + (bounds.size.height - rect.size.height), width: rect.size.width, height: rect.size.height)
    }
    }
    } else {
    //Fallback on earlier versions
    return rect
    }
    }
    override public func drawText(in rect: CGRect) {
    let r = self.textRect(forBounds: rect, limitedToNumberOfLines: self.numberOfLines)
    super.drawText(in: r)
    }
    }

  13. 1

    también puede cambiar su UILabel a UITextView, porque básicamente la misma cosa, excepto la ventaja de UITextView es que el texto se alinean automáticamente a la parte superior izquierda

  14. 0

    Para iOS 7 que es lo que hice y funcionó para mí

    @implementation UILabel (VerticalAlign)
    - (void)alignTop
    {
    CGSize boundingRectSize = CGSizeMake(self.frame.size.width, CGFLOAT_MAX);
    NSDictionary *attributes = @{NSFontAttributeName : self.font};
    CGRect labelSize = [self.text boundingRectWithSize:boundingRectSize options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
    attributes:attributes
    context:nil];
    int numberOfLines= ceil(labelSize.size.height / self.font.lineHeight);
    CGRect newFrame = self.frame;
    newFrame.size.height = numberOfLines * self.font.lineHeight;
    self.frame = newFrame;
    }
    - (void)alignBottom
    {
    CGSize boundingRectSize = CGSizeMake(self.frame.size.width, CGFLOAT_MAX);
    NSDictionary *attributes = @{NSFontAttributeName : self.font};
    CGRect labelSize = [self.text boundingRectWithSize:boundingRectSize options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
    attributes:attributes
    context:nil];
    int numberOfLines= ceil(labelSize.size.height / self.font.lineHeight);
    int numberOfNewLined = (self.frame.size.height/self.font.lineHeight) - numberOfLines;
    NSMutableString *newLines = [NSMutableString string];
    for(int i=0; i< numberOfNewLined; i++){
    [newLines appendString:@"\n"];
    }
    [newLines appendString:self.text];
    self.text = [newLines mutableCopy];
    }
  15. 0

    Swift 2.0: : El Uso De UILabel Extensión

    Constantes los valores de enumeración en un vacío Swift archivo.

    // AppRef.swift
    import UIKit
    import Foundation
    enum UILabelTextPositions : String {
    case VERTICAL_ALIGNMENT_TOP = "VerticalAlignmentTop"
    case VERTICAL_ALIGNMENT_MIDDLE = "VerticalAlignmentMiddle"
    case VERTICAL_ALIGNMENT_BOTTOM = "VerticalAlignmentBottom"
    }

    Utilizando UILabel Extensión:

    Hacer un vacío Swift de la clase y el nombre. Añadir el siguiente.

    // AppExtensions.swift
    import Foundation
    import UIKit
    extension UILabel{ 
    func makeLabelTextPosition (sampleLabel :UILabel?, positionIdentifier : String) -> UILabel
    {
    let rect = sampleLabel!.textRectForBounds(bounds, limitedToNumberOfLines: 0)
    switch positionIdentifier
    {
    case "VerticalAlignmentTop":
    sampleLabel!.frame = CGRectMake(bounds.origin.x+5, bounds.origin.y, rect.size.width, rect.size.height)
    break;
    case "VerticalAlignmentMiddle":
    sampleLabel!.frame = CGRectMake(bounds.origin.x+5,bounds.origin.y + (bounds.size.height - rect.size.height) / 2,
    rect.size.width, rect.size.height);
    break;
    case "VerticalAlignmentBottom":
    sampleLabel!.frame = CGRectMake(bounds.origin.x+5, bounds.origin.y + (bounds.size.height - rect.size.height),rect.size.width, rect.size.height);
    break;
    default:
    sampleLabel!.frame = bounds;
    break;
    }
    return sampleLabel!
    }
    }

    Uso :

    myMessageLabel.makeLabelTextPosition(messageLabel, positionIdentifier: UILabelTextPositions.VERTICAL_ALIGNMENT_TOP.rawValue)
    • Podría explicar qué es necesario para sampleLabel: UILabel??
    • En esta func makeLabelTextPosition (sampleLabel :UILabel?, positionIdentifier : String){}, tienes que pasar la UILabel objeto.
  16. 0

    Swift 3 versión de @totiG la respuesta de

    class UIVerticalAlignLabel: UILabel {
    enum VerticalAlignment : Int {
    case VerticalAlignmentTop = 0
    case VerticalAlignmentMiddle = 1
    case VerticalAlignmentBottom = 2
    }
    @IBInspectable var verticalAlignment : VerticalAlignment = .VerticalAlignmentTop {
    didSet {
    setNeedsDisplay()
    }
    }
    required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    }
    override func textRect(forBounds bounds: CGRect, limitedToNumberOfLines: Int) -> CGRect {
    let rect = super.textRect(forBounds: bounds, limitedToNumberOfLines: limitedToNumberOfLines)
    switch(verticalAlignment) {
    case .VerticalAlignmentTop:
    return CGRect(x: bounds.origin.x, y: bounds.origin.y, width: rect.size.width, height: rect.size.height)
    case .VerticalAlignmentMiddle:
    return CGRect(x: bounds.origin.x, y: bounds.origin.y + (bounds.size.height - rect.size.height) / 2, width: rect.size.width, height: rect.size.height)
    case .VerticalAlignmentBottom:
    return CGRect(x: bounds.origin.x, y: bounds.origin.y + (bounds.size.height - rect.size.height), width: rect.size.width, height: rect.size.height)
    }
    }
    override func drawText(in rect: CGRect) {
    let r = self.textRect(forBounds: rect, limitedToNumberOfLines: self.numberOfLines)
    super.drawText(in: r)
    }
    }
  17. -1

    Cómo definir la alineación a la izquierda para UILabel para la aplicación de iOS? Juego de etiquetas de Contenido a Modo de «Arriba a la Izquierda» trabajar para mí, muchas gracias:

    Cómo definir la alineación a la izquierda para UILabel para la aplicación de iOS?

    • No hace absolutamente nada para mí. Esto parece intuitivamente como debe ser la solución, que es por eso que recurrí a Google cuando no trabajan (o aparentemente hacer jack de todos, para que la materia).

Dejar respuesta

Please enter your comment!
Please enter your name here