web-dev-qa-db-fra.com

Comment définir la taille du contenu intrinsèque d'une vue personnalisée dans Swift?

Arrière-plan

Je crée une étiquette verticale à utiliser avec l’écriture mongole traditionnelle. Auparavant, je tournais UILabel, mais il y avait des problèmes de performances et d'autres complications. Maintenant, je travaille sur la création d'une étiquette à partir de zéro. Cependant, j'ai besoin de l'étiquette verticale pour indiquer la mise en page automatique lorsque sa hauteur est ajustée (en fonction de la longueur de la chaîne).

Ce que j'ai lu

J'ai lu la documentation taille du contenu intrinsèque et vues avec la taille du contenu intrinsèque . Celles-ci portaient plus sur la façon de l’utiliser, et non sur la façon de le définir dans une vue personnalisée.

La recherche de "taille de contenu intrinsèque ios pour une vue personnalisée" ne me donne que

débordement de pile. Cette question particulière n'avait même pas besoin de taille de contenu intrinsèque, car son point de vue n'était qu'un assemblage de vues standard.

Ce que j'essaie

Ce que j'essaie, c'est ma réponse ci-dessous. J'ajoute cette paire de questions-réponses afin que d'autres personnes ne mettent pas autant de temps à trouver la réponse, car cela m'a pris avec les mots-clés de recherche que j'ai utilisés.

39
Suragch

La définition de la taille de contenu intrinsèque d'une vue personnalisée permet à la mise en page automatique de connaître la taille de cette vue. Pour le définir, vous devez remplacer intrinsicContentSize.

override var intrinsicContentSize: CGSize {
   return CGSize(width: x, height: y)
}

Alors appelez

invalidateIntrinsicContentSize()

Chaque fois que la taille du contenu intrinsèque de votre vue personnalisée change et que le cadre doit être mis à jour.

Notes

76
Suragch

Exemple de "vue avec hauteur intrinsèque" ...

@IBDesignable class HView: UIView {

    @IBInspectable var height: CGFloat = 100.0

    override var intrinsicContentSize: CGSize {
        return CGSize(width: 99, height: height)
        // if using in, say, a vertical stack view, the width is ignored
    }

    override func prepareForInterfaceBuilder() {
         invalidateIntrinsicContentSize()
    }
}

enter image description here

que vous pouvez définir comme inspectable

enter image description here

Comme il a une hauteur intrinsèque, il peut (par exemple) être immédiatement inséré dans une vue de pile en code:

stack?.insertArrangedSubview(HView(), at: 3)

En revanche, s'il s'agissait d'une vue normale sans hauteur intrinsèque, vous devrez ajouter une ancre de hauteur, sinon elle planterait:

let v:UIView = HView()
v.heightAnchor.constraint(equalToConstant: 100).isActive = true
stack?.insertArrangedSubview(v, at: 3)

Notez que dans ...

le cas particulier important d'une vue de pile:

  • vous définissez uniquement [~ # ~] un [~ # ~] anchor (pour une vue verticale de la pile, la hauteur ; pour horizontal la largeur)

donc, régler la hauteur intrinsèque fonctionne parfaitement, puisque:

  • la hauteur intrinsèque signifie en effet que l'ancre de hauteur sera spécifiquement définie automatiquement si nécessaire.

Rappelez-vous que dans tous les cas normaux d'une sous-vue, de nombreux autres points d'ancrage sont nécessaires.

9
Fattie