J'ai une vue qui contient des lignes et des colonnes d'images vues.
Si cette vue est redimensionnée, je dois réorganiser les positions des vues d'image.
Cette vue est une sous-vue d'une autre vue qui est redimensionnée.
Existe-t-il un moyen de détecter le redimensionnement de cette vue?
Réponses:
Comme Uli l'a commenté ci-dessous, la bonne façon de le faire est de remplacer
layoutSubviews
et de mettre en page les imageViews ici.Si, pour une raison quelconque, vous ne pouvez pas sous-classer et remplacer
layoutSubviews
, l'observationbounds
devrait fonctionner, même si elle est un peu sale. Pire encore, il y a un risque avec l'observation - Apple ne garantit pas que KVO fonctionne sur les classes UIKit. Lisez la discussion avec l'ingénieur Apple ici: Quand un objet associé est-il publié?réponse originale:
Vous pouvez utiliser l'observation des valeurs-clés:
et mettre en œuvre:
la source
viewWillTransition
etc. etc.layoutSubviews
toujours recommandé d' utiliser une méthode si, en fonction de la taille actuelle de la vue, différentes sous-vues devaient être ajoutées / supprimées et différentes contraintes devaient être ajoutées / supprimées?Dans une
UIView
sous - classe, les observateurs de propriétés peuvent être utilisés:Sans sous-classification, l' observation de valeur-clé avec des chemins de clé intelligents fera:
la source
frame
est une propriété calculée dérivée et calculée à l'exécution. n'écrasez pas cela, sauf si vous avez une raison très intelligente et bien informée de le faire. sinon: utilisezbounds
ou (encore mieux)layoutSubviews
.override var bounds: CGRect { didSet { layer.cornerRadius = bounds.size.width / 2 }}
bounds
ou laframe
modification fonctionne, selon l'endroit où vous placez votre vue dans la hiérarchie des vues. Je remplaceraislayoutSubviews
plutôt. Voyez ceci et cela répond.Créer une sous-classe de UIView et remplacer la disposition
la source
Swift 4 keypath KVO - C'est ainsi que je détecte la rotation automatique et le déplacement vers le panneau latéral de l'iPad. Devrait fonctionner n'importe quelle vue. Dû observer la couche de l'UIView.
la source
.layer
a fait l'affaire! Savez-vous pourquoi l'utilisationview.observe
ne fonctionne pas?Vous pouvez créer une sous-classe de UIView et remplacer le
setFrame: cadre (CGRect)
méthode. C'est la méthode appelée lorsque le cadre (c'est-à-dire la taille) de la vue est modifié. Faites quelque chose comme ceci:
la source
setFrame:
n'a pas été appelé sur maUITextView
sous - classe lors du redimensionnement causé par l'autorotation alors quelayoutSubviews:
c'était. Remarque: j'utilise la mise en page automatique et iOS 7.0.setFrame:
.frame
est une propriété dérivée. Voir ma réponseAssez vieux mais toujours une bonne question. Dans l'exemple de code d'Apple et dans certaines de leurs sous-classes UIView privées, ils remplacent setBounds à peu près comme:
Remplacer
setFrame:
n'est PAS une bonne idée.frame
est dérivé decenter
,bounds
ettransform
, donc iOS n'appellera pas nécessairementsetFrame:
.la source
setBounds:
n'est pas appelée non plus lors de la définition de la propriété frame (au moins sur iOS 7.1). Cela pourrait être une optimisation ajoutée par Apple pour éviter le message supplémentaire.frame
etbounds
sont dérivés du sous-jacent de la vueCALayer
; ils appellent simplement le getter de la couche. EtsetFrame:
définit le cadre du calque, tandis quesetBounds:
définit les limites du calque. Vous ne pouvez donc pas simplement passer outre l'un ou l'autre. De plus,layoutSubviews
est appelé de manière excessive (pas seulement en cas de changements de géométrie), ce n'est donc pas toujours une bonne option non plus. Toujours à la recherche ...Si vous êtes dans une instance UIViewController, la substitution
viewDidLayoutSubviews
fait l'affaire.la source
UIView
instances et lesUIViewController
instances. Donc, si vous avez uneUIView
instance sans VC attaché, les autres réponses sont excellentes, mais si vous êtes attaché à un VC, c'est votre homme. Désolé, cela ne s'applique pas à votre cas.