[Swift] Legen Sie die Ränder für mehrere Zeilen der UI-Beschriftung fest: oben, unten, links und rechts

Einführung

Die Umwelt ist ・ Xcode 11.6 ・ Schnell 5 Wird sein.

Es gibt Zeiten, in denen Sie die Ränder (Auffüllungen) für Etiketten festlegen möchten, oder?

Verwenden Sie beispielsweise im Fall von textView "textContainerInset" und im Fall von UIButton "contentEdgeInsets" usw., und ich denke, dass dies relativ einfach festgelegt werden kann.

Bei UILabel ist dies jedoch etwas ärgerlich, insbesondere bei mehrzeiligem Text.

Versuchen Sie es zuerst

Insbesondere für die horizontalen Ränder kann attributedText es ordentlich lösen. Das Folgende ist ein Beispiel.

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

In vertikaler Richtung können Sie den Zeilenabstand und die Zeilenhöhe angeben, aber es ist eine Schande, dass Sie die Ränder nicht direkt festlegen können. Wenn der Text jedoch aus einer Zeile besteht, können Sie die Zeilenhöhe und die Schriftgröße gut einstellen, um den oberen und unteren Rand effektiv zu steuern.

Normalerweise ist das okay

Es ist eine gängige Suchmethode. Wenn Sie jedoch ein benutzerdefiniertes Label erstellen, das UILabel wie unten gezeigt erbt, wird es normalerweise gelöst.

Sie können den oberen, unteren, linken und rechten Rand richtig einstellen.


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
    }
}

Sie müssen hier nicht "sizeThatFits (_ size: CGSize)" haben, aber wenn Sie dies tun, wird es automatisch an die Größe einschließlich der Ränder angepasst, wenn Sie "sizeToFit ()" ausführen. Vielen Dank. Wenn Sie keine Ränder in "sizeToFit ()" aufnehmen möchten, überschreiben Sie diese natürlich nicht.

Letzter Ausweg

Wenn es ein Problem gibt, das durch das oben Gesagte nicht gelöst werden kann, ist dies wahrscheinlich der letzte Ausweg

UILabel( ) in UIView( )

Infolgedessen kann die übergeordnete Ansicht als Beschriftung (oder Schaltfläche) mit einem Rand behandelt werden, indem die Beschriftung an einer beliebigen Position in der übergeordneten Ansicht angeordnet wird, nachdem sie mit normalem "sizeToFit ()" in einem Zustand ohne Rand erstellt wurde.

In diesem Fall müssen Sie hier die Größe der übergeordneten Ansicht angeben, aber Sie sollten in der Lage sein, mit sizeToFit () + AutoLayout halbautomatisch zu arbeiten.

Schließlich

Bitte lassen Sie mich wissen, ob es einen anderen guten Weg gibt!

Recommended Posts

[Swift] Legen Sie die Ränder für mehrere Zeilen der UI-Beschriftung fest: oben, unten, links und rechts
Stellen Sie die Anzahl der Sekunden für den schnellen Vor- und Rücklauf in ExoPlayer ein
Vergleichen Sie die Geschwindigkeit der for-Anweisung und der erweiterten for-Anweisung.