web-dev-qa-db-fra.com

Comment forcer le redessinage (drawRect) d'une sous-vue lorsqu'elle change de dimension?

J'ai un UIView qui contient une rangée de sous-classes de UIView. La sous-classe a remplacé drawRect: et a défini contentMode = UIViewContentModeRedraw.

Lorsque l'utilisateur écrase et étire le conteneur parent, child views écrase et étire. Lorsque le changement de forme se produit, j'aimerais que drawRect soit appelé à plusieurs reprises pour modifier le contenu du child views. Jusqu'à présent, j'ai échoué. Quelle est la bonne façon de faire cela?

À votre santé,

Doug

23
dugla

Dans Cocoa, vous appelez rarement (voire jamais) drawRect. Il vous suffit de marquer la région ou la vue comme nécessitant une mise à jour. Le redessinage est planifié. Cela permet de redessiner plusieurs retraits pour plusieurs invalidations. 

Pour Cocoa Touch, vous voulez soit [view setNeedsDisplay] , ou setNeedsDisplayinRect: (CGRect)

58
Adam Wright

Vous devez appeler [view setNeedsLayout] pour que les sous-vues reçoivent un appel drawRect: si la présentation change. Je n'ai pas testé cela, cependant.

3
Pascal

Cette solution est un peu folle, mais elle est logique et donne un excellent résultat visuel. Je travaille avec un NSLayoutManager et un couple NSTextContainers, en disposant le texte sur deux colonnes. Comme j'utilise plusieurs conteneurs de texte (et que je ne suis pas sûr de vouloir plusieurs UITextView), je remplace la méthode draw(rect: CGRect) de MyDrawingView: UIView

Le problème est que l'utilisation de self.contentMode = .redraw entraîne toujours des étirements mineurs en rotation, suffisamment importants pour que cela brise la donne.

J'ai remarqué que le réglage de contentMode = .left, voire de contentMode = .scaleAspectFit était proche de ce que je voulais, en termes de rotation pixel-perfect. Mais évidemment, je n'ai pas eu l'appel du tirage dont j'avais besoin.

Alors, j’ai remplacé layoutSubviews(), changé la contentMode en .scaleAspectFit, appelé super.layoutSubviews(), puis l’a remis sous tension. : P

override func layoutSubviews() {
    self.contentMode = .scaleAspectFit

    super.layoutSubviews()
    self.contentMode = .redraw
}

Il est parfait.

0
Stan