web-dev-qa-db-fra.com

Sous-classe UILabel - le texte est coupé en bas bien que la hauteur de l'étiquette soit correcte

J'ai un problème avec la sous-classe UILabel qui coupe le texte en bas. L'étiquette a la bonne hauteur pour s'adapter au texte, il reste un peu d'espace en bas, mais le texte est toujours coupé.

 The label

Les bandes rouges sont des bordures ajoutées au calque de l'étiquette.

Je sous-classe l'étiquette pour ajouter des incrustations Edge.

override func sizeThatFits(size: CGSize) -> CGSize {
    var size = super.sizeThatFits(size)
    size.width += insets.left + insets.right
    size.height += insets.top + insets.bottom
    return size
}

override func drawTextInRect(rect: CGRect) {
    super.drawTextInRect(UIEdgeInsetsInsetRect(rect, insets))
}

Cependant, dans ce cas particulier, les incrustations sont nulles.

9
mag_zbc

Il s'avère que le problème était avec

self.lineBreakMode = .ByClipping

en le changeant en

self.lineBreakMode = .ByCharWrapping

Résolu le problème

9
mag_zbc

Cela m’est arrivé lorsque j’ai fourni topAnchor et centerYAnchor en même temps. Le problème n’a pas été résolu.

2
AlekseiPetrovski

Mon problème était que la priorité de résistance de compression de contenu (verticale) de l'étiquette n'était pas assez élevée; en le réglant sur required (1000), il l'a corrigé.

Il semble que les autres réponses non-OP peuvent être une sorte de solution de contournement pour ce même problème sous-jacent.

1
juliand665

D'autres réponses ne m'ont pas aidé, mais ce qui a contraint la taille de l'étiquette à la hauteur souhaitée, comme suit:

let unconstrainedSize = CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude)
label.heightAnchor.constraint(equalToConstant: label.sizeThatFits(unconstrainedSize).height).isActive = true

De plus, sizeThatFits(_:) renverra une taille 0 by 0 si le champ text de votre étiquette est nil ou est égal à ""

1
shoe

J'ai aussi rencontré ce problème, mais je voulais éviter d'ajouter une contrainte de hauteur. J'avais déjà créé une sous-classe UILabel qui me permettait d'ajouter des encarts de contenu (mais dans le but de définir tableHeaderView directement sur une étiquette sans avoir à la contenir dans une autre vue). En utilisant la classe, je pouvais définir l’encart du bas pour résoudre le problème de la coupure de police.

import UIKit

@IBDesignable class InsetLabel: UILabel {

    @IBInspectable var topInset: CGFloat = 16
    @IBInspectable var bottomInset: CGFloat = 16
    @IBInspectable var leftInset: CGFloat = 16
    @IBInspectable var rightInset: CGFloat = 16
    var insets: UIEdgeInsets {
        get {
            return UIEdgeInsets(
                top: topInset,
                left: leftInset,
                bottom: bottomInset,
                right: rightInset
            )
        }
    }

    override func drawText(in rect: CGRect) {
        super.drawText(in: rect.inset(by: insets))
    }

    override var intrinsicContentSize: CGSize {
        return addInsetsTo(size: super.intrinsicContentSize)
    }

    override func sizeThatFits(_ size: CGSize) -> CGSize {
        return addInsetsTo(size: super.sizeThatFits(size))
    }

    func addInsetsTo(size: CGSize) -> CGSize {
        return CGSize(
            width: size.width + leftInset + rightInset,
            height: size.height + topInset + bottomInset
        )
    }

}

Cela pourrait être simplifié simplement pour la découpe de police en:

import UIKit

class FontFittingLabel: UILabel {

    var inset: CGFloat = 16 // Adjust this

    override func drawText(in rect: CGRect) {
        super.drawText(in: rect.inset(by: UIEdgeInsets(
            top: 0,
            left: 0,
            bottom: inset,
            right: 0
        )))
    }

    override var intrinsicContentSize: CGSize {
        let size = super.intrinsicContentSize
        return CGSize(
            width: size.width,
            height: size.height + inset
        )
    }

}
0
Robin Douglas