[Swift] Définissez les marges de plusieurs lignes d'étiquette d'interface utilisateur: haut, bas, gauche et droite

introduction

L'environnement est ・ Xcode 11.6 ・ Swift 5 Sera.

Il y a des moments où vous souhaitez définir les marges (remplissage) pour les étiquettes, non?

Par exemple, dans le cas de textView, utilisez textContainerInset, et dans le cas d'UIButton, utilisez contentEdgeInsets, etc., et je pense que cela peut être défini relativement facilement.

Mais avec UILabel, c'est un peu ennuyeux, surtout avec du texte multiligne.

Essayez d'abord

Surtout pour les marges horizontales, ʻattributedText` peut le résoudre proprement. Ce qui suit est un exemple.

let style = NSMutableParagraphStyle()
// horizontal setting
style.headIndent = 0
style.tailIndent = 0
// vertical setting
style.lineSpacing = 0
style.maximumLineHeight = 16
style.minimumLineHeight = 16
style.paragraphSpacingBefore = 10
style.paragraphSpacing = 30

let attr: [NSAttributedString.Key : Any] = [
    .font: ...,
    .paragraphStyle : style,
]
let attributedText = NSAttributedString(string: "hoge", attributes: attr)

let label = UILabel()
label.attributedText = attributedText

Dans le sens vertical, vous pouvez spécifier l'espacement et la hauteur de ligne, mais il est dommage que vous ne puissiez pas définir les marges directement. Cependant, si le texte est une ligne, vous pouvez définir correctement la hauteur de ligne et la taille de la police pour contrôler efficacement les marges supérieure et inférieure.

Habituellement, ça va

C'est une méthode courante de recherche, mais si vous créez une étiquette personnalisée qui hérite de UILabel comme indiqué ci-dessous, elle sera généralement résolue.

Vous pouvez définir correctement les marges supérieure, inférieure, gauche et droite.


class PaddingLabel: UILabel {

    var padding: UIEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)

    override func drawText(in rect: CGRect) {
        let newRect = rect.inset(by: padding)
        super.drawText(in: newRect)
    }

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

Vous n'avez pas besoin d'avoir sizeThatFits (_ size: CGSize) ici, mais si vous le faites, il s'ajustera automatiquement à la taille, y compris les marges lorsque vous faites sizeToFit (), donc je vous en suis reconnaissant. Bien sûr, si vous ne voulez pas inclure de marges dans sizeToFit (), ne le remplacez pas.

Dernier recours

S'il y a un problème qui ne peut pas être résolu par ce qui précède, le dernier recours est probablement

UILabel( ) in UIView( )

En conséquence, la vue parente peut être traitée comme une étiquette (ou un bouton) avec une marge en organisant l'étiquette à une position arbitraire dans la vue parente après l'avoir mise dans un état sans marge par sizeToFit () normal.

Dans ce cas, vous devez spécifier la taille de la vue parente ici, mais vous devriez pouvoir semi-automatiser avec sizeToFit () + ʻAutoLayout`.

finalement

S'il vous plaît laissez-moi savoir s'il existe un autre bon moyen!

Recommended Posts

[Swift] Définissez les marges de plusieurs lignes d'étiquette d'interface utilisateur: haut, bas, gauche et droite
Définissez le nombre de secondes d'avance et de retour rapides dans ExoPlayer
Comparez la vitesse de l'instruction for et de l'instruction for étendue.