Como controlar o espaçamento entre linhas no UILabel

274

É possível reduzir a diferença entre o texto, quando colocado em várias linhas em um UILabel? Podemos definir o quadro, tamanho da fonte e número de linhas. Eu quero reduzir a diferença entre as duas linhas nesse rótulo.

Abhinav
fonte
2
Posso sugerir que você aceite uma das respostas corretas para o iOS 6.0 e posterior? A resposta atualmente aceita está desatualizada.
Mark Amery
Para cada linha, use um novo UILabele incorpore todos os rótulos a StackView. Finalmente ajuste o spacingde StackView. Lembre-se de empilhá-los verticalmente.
Querida
Consulte o link a seguir para obter a solução no Swift 2. stackoverflow.com/a/39158698/6602495
Sneha
Consulte stackoverflow.com/a/44325650/342794 para obter detalhes sobre o storyboard e outros detalhes.
lal

Respostas:

262

Pensei em adicionar algo novo a esta resposta, para não me sentir tão mal ... Aqui está uma resposta rápida :

import Cocoa

let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 40

let attrString = NSMutableAttributedString(string: "Swift Answer")
attrString.addAttribute(.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attrString.length))

var tableViewCell = NSTableCellView()
tableViewCell.textField.attributedStringValue = attrString

"Resposta curta: você não pode. Para alterar o espaçamento entre linhas de texto, você terá que subclassificar UILabel e rolar seu próprio drawTextInRect, ou criar vários rótulos."

Consulte: Definir espaçamento entre linhas do UILabel


Esta é uma resposta muito antiga e outras já adicionaram a nova e melhor maneira de lidar com isso. Consulte as respostas atualizadas fornecidas abaixo.

Mazyod
fonte
23
Desde o iOS 6.0, você pode controlá-lo via NSAttributedString(também disponível nas propriedades do UILable no construtor de interface do Xcode).
ıɾuǝʞ
13
Curiosamente, o mais próximo que posso dizer, você pode adicionar espaçamento extra entre as linhas, mas não reduzi-lo através do NSParagraphStyleuso de um NSAttributedString. (I pode precisar de fazer mais testes das outras propriedades modifyable, mas a lineSpacingpropriedade só permite aumentá-lo.)
livingtech
veja a minha resposta para ver uma maneira usando NSAttributedString
d.ennis
2
@livingtech Isso é irritante, e acredito que você está correto. Você encontrou alguma solução alternativa?
Dom Vinyard
7
Apenas para esclarecer algo nesta discussão. Se você deseja reduzir o espaçamento entre linhas definir a altura da linha para 1,0, e depois setLineHeightMultiple para um valor inferior <1,0, como: [paragraphStyle setLineHeightMultiple: 0.8] ou paragraphStyle.lineHeightMultiple = 0,8
virsunen
401

No Xcode 6, você pode fazer isso no storyboard:

insira a descrição da imagem aqui

Mike S
fonte
1
Tire mais vantagens do storyboard!
Allen
22
O @PaperThick tem o mesmo problema no 6.1.1. "Harlem shake" por alguns minutos. Não sabe como corrigi-lo :) Xcode Shaking
Anton Gaenko 16/01
8
Existe uma maneira de definir fontes personalizadas dessa maneira? Não consigo mudar essa helvética neue para nenhuma outra fonte.
Marcos Curvello
2
Se você habilitar 'Attributed' e, em seguida, abrir o arquivo como código-fonte, poderá editar o 'lineHeightMultiple' manualmente e, portanto, ignorar o bug do Harlem Shake
ED-209
2
@azdev para qualquer um que ainda esteja olhando para isso, eu estou mais começando a sacudir no Xcode 7.3, mas acho que essa é a primeira versão em que não tem sido um problema
#
103

A partir do iOS 6, você pode definir uma sequência atribuída ao UILabel. Verifique o seguinte:

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:label.text];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineSpacing = spacing;
[attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, label.text.length)];

label.attributedText = attributedString;
iosMentalist
fonte
1
O attributedStringdeve ser um NSMutableAttributedString(NÃO NSAttributedString)
Mike S
14
O primeiro código de linha deve serNSMutableAttributedString *attributedString = [NSMutableAttributedString alloc]initWithString:@"sample text"];
Allen
A lineSpacingpropriedade do NSMutableParagraphStylenunca é negativa; portanto, a altura da linha não pode ser reduzida com essa abordagem. Para responder à pergunta, você precisa usar outra propriedade, consulte @ d.ennis answer.
Theo
81

As soluções indicadas aqui não funcionaram para mim. Encontrei uma maneira ligeiramente diferente de fazer isso com o iOS 6 NSAttributeString:

myLabel.numberOfLines = 0; 
NSString* string = @"String with line one. \n Line two. \n Line three.";
NSMutableParagraphStyle *style  = [[NSMutableParagraphStyle alloc] init];
style.minimumLineHeight = 30.f;
style.maximumLineHeight = 30.f;
NSDictionary *attributtes = @{NSParagraphStyleAttributeName : style,};
myLabel.attributedText = [[NSAttributedString alloc] initWithString:string
                                                         attributes:attributtes];   
[myLabel sizeToFit];
d.ennis
fonte
1
A altura da linha depende do tamanho da fonte. O espaçamento entre linhas é exatamente isso, espaçamento entre linhas. Você pode resolver o problema definindo apenas a altura da linha mínima / máxima, mas isso ocorre apenas porque os tamanhos de fonte atuais que você está usando não são maiores que os limites da altura da linha. De acordo com a documentação: "... glifos e gráficos que excedem essa altura se sobrepõem às linhas vizinhas ... Embora esse limite se aplique à própria linha, o espaçamento entre linhas adiciona espaço extra entre as linhas adjacentes".
Ari Braginsky 17/10
+1, se você deseja reduzir o espaçamento entre linhas, é isso que você deseja fazer. O espaçamento real das linhas provavelmente é 0, por padrão, é por isso que as pessoas relatam que você só pode aumentá-lo. O problema de o espaçamento ser muito grande vem da altura da linha ser muito grande, é por isso que isso fará o trabalho 99% do tempo.
lawicko
1
Esta é a única resposta que pude encontrar que usa o valor real da altura da linha (em vez de uma proporção) comum para projetar aplicativos como Photoshop, Sketch, CSS etc.
Albert Bori
35

Eu fiz essa extensão simples que funciona muito bem para mim:

extension UILabel {
    func setLineHeight(lineHeight: CGFloat) {
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineSpacing = 1.0
        paragraphStyle.lineHeightMultiple = lineHeight
        paragraphStyle.alignment = self.textAlignment

        let attrString = NSMutableAttributedString()
        if (self.attributedText != nil) {
            attrString.append( self.attributedText!)
        } else {
            attrString.append( NSMutableAttributedString(string: self.text!))
            attrString.addAttribute(NSAttributedStringKey.font, value: self.font, range: NSMakeRange(0, attrString.length))
        }
        attrString.addAttribute(NSAttributedStringKey.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attrString.length))
        self.attributedText = attrString
    }
}

Copie isso em um arquivo, para que você possa usá-lo assim

myLabel.setLineHeight(0.7)
Agustin Meriles
fonte
lembre-se de fazer isso enquanto você também está usando o Storyboard para esse rótulo, defina as linhas do rótulo como 0
Honey
Por que você simplesmente não define diretamente lineSpacinge esquece a configuração lineHeightMultiple?
Mel
Porque a chave para reduzir a altura da linha é 'lineHeightMultiple', não linespacing
Agustin Meriles
diz que quer sua altura linha para ser 1.4, por que você não pode simplesmente escrever .lineSpacing = 1.4e esquecer tudo sobre .lineHeightMultiple...
Mel
Hah! Tentei e não funcionei, mas me pergunto por que não vejo outras respostas aqui sem usar seu mecanismo, quero dizer que elas apenas definem diretamente o espaçamento entre linhas. Veja a resposta aceita ...
Mel
33

No Interface Builder (Storyboard / XIB):

insira a descrição da imagem aqui

Programaticamente:

SWift 4

Usando extensão de etiqueta

extension UILabel {

    // Pass value for any one of both parameters and see result
    func setLineSpacing(lineSpacing: CGFloat = 0.0, lineHeightMultiple: CGFloat = 0.0) {

        guard let labelText = self.text else { return }

        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineSpacing = lineSpacing
        paragraphStyle.lineHeightMultiple = lineHeightMultiple

        let attributedString:NSMutableAttributedString
        if let labelattributedText = self.attributedText {
            attributedString = NSMutableAttributedString(attributedString: labelattributedText)
        } else {
            attributedString = NSMutableAttributedString(string: labelText)
        }

        // Line spacing attribute
        attributedString.addAttribute(NSAttributedStringKey.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))

        self.attributedText = attributedString
    }
}

Agora chame a função de extensão

let label = UILabel()
let stringValue = "How to\ncontrol\nthe\nline spacing\nin UILabel"

// Pass value for any one argument - lineSpacing or lineHeightMultiple
label.setLineSpacing(lineSpacing: 2.0) .  // try values 1.0 to 5.0

// or try lineHeightMultiple
//label.setLineSpacing(lineHeightMultiple = 2.0) // try values 0.5 to 2.0

Ou usando a instância do rótulo (basta copiar e executar este código para ver o resultado)

let label = UILabel()
let stringValue = "How to\ncontrol\nthe\nline spacing\nin UILabel"
let attrString = NSMutableAttributedString(string: stringValue)
var style = NSMutableParagraphStyle()
style.lineSpacing = 24 // change line spacing between paragraph like 36 or 48
style.minimumLineHeight = 20 // change line spacing between each line like 30 or 40

// Line spacing attribute
attrString.addAttribute(NSAttributedStringKey.paragraphStyle, value: style, range: NSRange(location: 0, length: stringValue.characters.count))

// Character spacing attribute
attrString.addAttribute(NSAttributedStringKey.kern, value: 2, range: NSMakeRange(0, attrString.length))

label.attributedText = attrString

Swift 3

let label = UILabel()
let stringValue = "How to\ncontrol\nthe\nline spacing\nin UILabel"
let attrString = NSMutableAttributedString(string: stringValue)
var style = NSMutableParagraphStyle()
style.lineSpacing = 24 // change line spacing between paragraph like 36 or 48
style.minimumLineHeight = 20 // change line spacing between each line like 30 or 40
attrString.addAttribute(NSParagraphStyleAttributeName, value: style, range: NSRange(location: 0, length: stringValue.characters.count))
label.attributedText = attrString
Krunal
fonte
2
Adicione a linha "paragraphStyle.alignment = self.textAlignment" para manter o alinhamento original. Caso contrário, o texto será alinhado à esquerda.
Nithin Michael 29/04/19
Para quem perde reticências em textos grandes, use: paragraphStyle.lineBreakMode = .byTruncatingTail
christostsang
16

Aqui está uma classe que subclasse UILabel para ter propriedade de altura da linha: https://github.com/LemonCake/MSLabel

adriendenat
fonte
Isso funcionou para mim, obrigado. Eu também tentei usar o MTLabel, mas este foi melhor.
Denis Kutlubaev
1
Alguém sabe se o MSLabel suporta o caractere '\ n'?
Achi
11

Em Swift e em função, inspirado no DarkDust

// Usage: setTextWithLineSpacing(myEpicUILabel,text:"Hello",lineSpacing:20)
func setTextWithLineSpacing(label:UILabel,text:String,lineSpacing:CGFloat)
{
    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.lineSpacing = lineSpacing

    let attrString = NSMutableAttributedString(string: text)
    attrString.addAttribute(NSAttributedString.Key.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attrString.length))

    label.attributedText = attrString
}
Thyselius
fonte
7

De acordo com a Resposta do @Mike, reduzir o lineHeightMultipleé o ponto principal. Exemplo abaixo, funciona bem para mim:

    NSString* text = label.text;
    CGFloat textWidth = [text sizeWithAttributes:@{NSFontAttributeName: label.font}].width;
    if (textWidth > label.frame.size.width) {
        NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];
        paragraph.alignment = NSTextAlignmentCenter;
        paragraph.lineSpacing = 1.0f;
        paragraph.lineHeightMultiple = 0.75;     // Reduce this value !!!
        NSMutableAttributedString* attrText = [[NSMutableAttributedString alloc] initWithString:text];
        [attrText addAttribute:NSParagraphStyleAttributeName value:paragraph range:NSMakeRange(0, text.length)];
        label.attributedText = attrText;
    }
isaacselement
fonte
6

Extensão útil do SWIFT 3 para definir espaço entre linhas com mais facilidade :)

extension UILabel
{
    func setLineHeight(lineHeight: CGFloat)
    {
        let text = self.text
        if let text = text 
        {

            let attributeString = NSMutableAttributedString(string: text)
            let style = NSMutableParagraphStyle()

           style.lineSpacing = lineHeight
           attributeString.addAttribute(NSParagraphStyleAttributeName,
                                        value: style,
                                        range: NSMakeRange(0, text.characters.count))

           self.attributedText = attributeString
        }
    }
}
Kevin Sabbe
fonte
5

Eu encontrei uma maneira em que você pode definir a altura real da linha (não é um fator) e até renderiza no Interface Builder . Apenas siga as instruções abaixo. O código está escrito no Swift 4 .


Etapa 1: Crie um arquivo nomeado DesignableLabel.swifte insira o seguinte código:

import UIKit

@IBDesignable
class DesignableLabel: UILabel {
    @IBInspectable var lineHeight: CGFloat = 20 {
        didSet {
            let paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.minimumLineHeight = lineHeight
            paragraphStyle.maximumLineHeight = lineHeight
            paragraphStyle.alignment = self.textAlignment

            let attrString = NSMutableAttributedString(string: text!)
            attrString.addAttribute(NSAttributedStringKey.font, value: font, range: NSRange(location: 0, length: attrString.length))
            attrString.addAttribute(NSAttributedStringKey.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: attrString.length))
            attributedText = attrString
        }
    }
}

Etapa 2: Coloque um UILabelem um Storyboard / XIB e defina sua classe como DesignableLabel. Aguarde a construção do seu projeto (a construção deve ser bem-sucedida!).

Especificando a classe para seu UILabel


Etapa 3: Agora você deve ver uma nova propriedade no painel de propriedades denominada "Altura da linha". Basta definir o valor desejado e você verá os resultados imediatamente!

Definir altura da linha nas propriedades

Jeehut
fonte
2

Aqui está uma subclasse de UILabel que define lineHeightMultiplee garante que a altura intrínseca seja grande o suficiente para não cortar o texto.

@IBDesignable
class Label: UILabel {
    override var intrinsicContentSize: CGSize {
        var size = super.intrinsicContentSize
        let padding = (1.0 - lineHeightMultiple) * font.pointSize
        size.height += padding
        return size
    }

    override var text: String? {
        didSet {
            updateAttributedText()
        }
    }

    @IBInspectable var lineHeightMultiple: CGFloat = 1.0 {
        didSet {
            updateAttributedText()
        }
    }

    private func updateAttributedText() {
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineHeightMultiple = lineHeightMultiple
        attributedText = NSAttributedString(string: text ?? "", attributes: [
            .font: font,
            .paragraphStyle: paragraphStyle,
            .foregroundColor: textColor
        ])
        invalidateIntrinsicContentSize()
    }
}
phatmann
fonte
preenchimento extra deve ser (lineHeightMultiple - 1.0) * font.pointSize, certo?
Pavel Alexeev
O código acima como está parecia funcionar para mim. Mas talvez você esteja certo. Você tentou a sua mudança? @PavelAlexeev
phatmann
Não, eu fico com lineSpacing em vez de lineHeightMultiple :)
Pavel Alexeev
1

No Swift 2.0 ...

Adicione uma extensão:

extension UIView {
    func attributesWithLineHeight(font: String, color: UIColor, fontSize: CGFloat, kern: Double, lineHeightMultiple: CGFloat) -> [String: NSObject] {
        let titleParagraphStyle = NSMutableParagraphStyle()
        titleParagraphStyle.lineHeightMultiple = lineHeightMultiple

        let attribute = [
            NSForegroundColorAttributeName: color,
            NSKernAttributeName: kern,
            NSFontAttributeName : UIFont(name: font, size: fontSize)!,
            NSParagraphStyleAttributeName: titleParagraphStyle
        ]
        return attribute
    }
}

Agora, basta definir seu UILabel como attributeText:

self.label.attributedText = NSMutableAttributedString(string: "SwiftExample", attributes: attributesWithLineHeight("SourceSans-Regular", color: UIColor.whiteColor(), fontSize: 20, kern: 2.0, lineHeightMultiple: 0.5))    

Obviamente, adicionei vários parâmetros que talvez você não precise. Brinque - sinta-se à vontade para reescrever o método - Eu estava procurando isso em várias respostas diferentes, então achei que postaria toda a extensão, caso isso ajude alguém por aí ... -rab

rab_w
fonte
1

Swift3 - Em uma extensão UITextView ou UILabel, adicione esta função:

Adicionei algum código para manter o texto atribuído atual, se você já estiver usando cadeias atribuídas com a visualização (em vez de substituí-las).

func setLineHeight(_ lineHeight: CGFloat) {
    guard let text = self.text, let font = self.font else { return }

    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.lineSpacing = 1.0
    paragraphStyle.lineHeightMultiple = lineHeight
    paragraphStyle.alignment = self.textAlignment

    var attrString:NSMutableAttributedString
    if let attributed = self.attributedText {
        attrString = NSMutableAttributedString(attributedString: attributed)
    } else {
        attrString = NSMutableAttributedString(string: text)
        attrString.addAttribute(NSFontAttributeName, value: font, range: NSMakeRange(0, attrString.length))
    }
    attrString.addAttribute(NSParagraphStyleAttributeName, value:paragraphStyle, range:NSMakeRange(0, attrString.length))
    self.attributedText = attrString
}
rmooney
fonte
1

Outra resposta ... Se você estiver passando a sequência de forma programática, precisará passar uma sequência atribuída em vez de uma sequência regular e alterar seu estilo. (IOS10)

NSMutableAttributedString * attrString = [[NSMutableAttributedString alloc] initWithString:@"Your \nregular \nstring"];
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
[style setLineSpacing:4];
[attrString addAttribute:NSParagraphStyleAttributeName
                   value:style
                   range:NSMakeRange(0, attrString.length)];
_label.attributedText = attrString;
Ricardo Mutti
fonte
1

Extensão Swift 3:

    import UIKit

extension UILabel {
    func setTextWithLineSpacing(text: String, lineHeightMultiply: CGFloat = 1.3) {
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineHeightMultiple = lineHeightMultiply
        paragraphStyle.alignment = .center
        let attributedString = NSMutableAttributedString(string: text)
        attributedString.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range: NSRange(location: 0, length: attributedString.length))
        self.attributedText = attributedString
    }
}
Roman Barzyczak
fonte
1

Isso deve ajudar com isso. Em seguida, você pode atribuir seu rótulo a essa classe personalizada no storyboard e usá-lo diretamente nos parâmetros:

open class SpacingLabel : UILabel {

    @IBInspectable open var lineHeight:CGFloat = 1 {
        didSet {
            let paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.lineSpacing = 1.0
            paragraphStyle.lineHeightMultiple = self.lineHeight
            paragraphStyle.alignment = self.textAlignment

            let attrString = NSMutableAttributedString(string: self.text!)
            attrString.addAttribute(NSAttributedStringKey.font, value: self.font, range: NSMakeRange(0, attrString.length))
            attrString.addAttribute(NSAttributedStringKey.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attrString.length))
            self.attributedText = attrString
        }
    } 
}
Russell Warwick
fonte
Isso deve ajudar com isso. Em seguida, você pode atribuir seu rótulo a essa classe personalizada no storyboard e usá-lo diretamente dentro das propriedades.
Russell Warwick
não coloque conteúdo relacionado à sua resposta nos comentários. sua resposta deve ser útil sem ter que ler através dos comentários
Neuron
1

Extensão de etiqueta Swift 4. Criando NSMutableAttributedString antes de passar para a função, caso haja atributos adicionais necessários para o texto atribuído.

extension UILabel {

    func setLineHeightMultiple(to height: CGFloat, withAttributedText attributedText: NSMutableAttributedString) {

        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineSpacing = 1.0
        paragraphStyle.lineHeightMultiple = height
        paragraphStyle.alignment = textAlignment

        attributedText.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: attributedText.length - 1))

        self.attributedText = attributedText
    }
}
Edward
fonte
0

Este código funcionou para mim (iOS 7 e iOS 8, com certeza).

_label.numberOfLines=2;
_label.textColor=[UIColor whiteColor];

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineHeightMultiple=0.5;
paragraphStyle.alignment = NSTextAlignmentCenter;
paragraphStyle.lineSpacing = 1.0;

NSDictionary *nameAttributes=@{
                               NSParagraphStyleAttributeName : paragraphStyle,
                               NSBaselineOffsetAttributeName:@2.0
                               };


NSAttributedString *string=[[NSAttributedString alloc] initWithString:@"22m\nago" attributes:nameAttributes];
_label.attributedText=string;
daniel kilinskas
fonte
0

Aqui está a minha solução rapidamente. A subclasse deve funcionar para as propriedades attributeText e text e para characterSpacing + lineSpacing. Ele mantém o espaçamento se uma nova string ou attributeString for configurada.

open class UHBCustomLabel : UILabel {
    @IBInspectable open var characterSpacing:CGFloat = 1 {
        didSet {
            updateWithSpacing()
        }

    }
    @IBInspectable open var lines_spacing:CGFloat = -1 {
        didSet {
            updateWithSpacing()
        }

    }
    open override var text: String? {
        set {
            super.text = newValue
            updateWithSpacing()
        }
        get {
            return super.text
        }
    }
    open override var attributedText: NSAttributedString? {
        set {
            super.attributedText = newValue
            updateWithSpacing() 
        }
        get {
            return super.attributedText
        }
    }
    func updateWithSpacing() {
        let attributedString = self.attributedText == nil ? NSMutableAttributedString(string: self.text ?? "") : NSMutableAttributedString(attributedString: attributedText!)
        attributedString.addAttribute(NSKernAttributeName, value: self.characterSpacing, range: NSRange(location: 0, length: attributedString.length))
        if lines_spacing >= 0 {
            let paragraphStyle = NSMutableParagraphStyle()
            paragraphStyle.lineSpacing = lines_spacing
            paragraphStyle.alignment = textAlignment
            attributedString.addAttribute(NSParagraphStyleAttributeName, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))
        }
        super.attributedText = attributedString
    }
}
Umair
fonte
-5

Como uma solução rápida, rápida, suja, inteligente e simples:

Para UILabels que não têm muitas linhas, você pode usar o stackViews.

  1. Para cada linha, escreva um novo rótulo.
  2. Incorpore-os ao StackView. (Selecione os dois rótulos -> Editor -> Incorporar -> StackView
  3. Ajuste o SpacingStackView para a quantidade desejada

Empilhe-os verticalmente . Essa solução também funciona para fontes personalizadas.

insira a descrição da imagem aqui

Mel
fonte
FWIW, esta é uma solução terrível, mas viável. Portanto, eu estou mantendo isso.
Mel
Eu também vi um princípio do iOS Dev usar stackviews para criar gráficos. Stackviews são muito poderosas
Mel