Tengo una vista que tiene filas y columnas de vistas de imágenes.
Si se cambia el tamaño de esta vista, necesito reorganizar las posiciones de las vistas de imágenes.
Esta vista es una subvista de otra vista cuyo tamaño cambia.
¿Hay alguna forma de detectar cuándo se está cambiando el tamaño de esta vista?
Respuestas:
Como comentó Uli a continuación, la forma correcta de hacerlo es anular
layoutSubviews
y diseñar los imageViews allí.Si, por alguna razón, no puede subclasificar y anular
layoutSubviews
, la observaciónbounds
debería funcionar, incluso cuando esté algo sucio. Peor aún, existe un riesgo al observar: Apple no garantiza que KVO funcione en las clases de UIKit. Lea la discusión con el ingeniero de Apple aquí: ¿ Cuándo se libera un objeto asociado?respuesta original:
Puede utilizar la observación de pares clave-valor:
e implementar:
fuente
viewWillTransition
etc., etc.layoutSubviews
Sigue siendo un método recomendado si, según el tamaño actual de la vista, se deben agregar / eliminar diferentes subvistas y se deben agregar / eliminar diferentes restricciones?En una
UIView
subclase, se pueden utilizar observadores de propiedades :Sin subclases, clave-valor observación con clave caminos inteligentes hará:
fuente
frame
es una propiedad derivada y calculada en tiempo de ejecución. no anule esto, a menos que tenga una razón muy inteligente y consciente para hacerlo. de lo contrario: usebounds
o (incluso mejor)layoutSubviews
.override var bounds: CGRect { didSet { layer.cornerRadius = bounds.size.width / 2 }}
bounds
o elframe
cambio funcionen, dependiendo de dónde coloque su vista en la jerarquía de vistas. En sulayoutSubviews
lugar, anularía . Vea esta y esta respuesta.Cree una subclase de UIView y anule el diseño
fuente
Swift 4 keypath KVO: así es como detecto la rotación automática y el movimiento al panel lateral del iPad. Debería funcionar trabajar cualquier vista. Tuve que observar la capa de UIView.
fuente
.layer
¡Hizo el truco! ¿Sabes por quéview.observe
no funciona el uso?Puede crear una subclase de UIView y anular la
setFrame: marco (CGRect)
método. Este es el método llamado cuando se cambia el marco (es decir, el tamaño) de la vista. Haz algo como esto:
fuente
setFrame:
no se llamó a miUITextView
subclase durante el cambio de tamaño causado por la autorrotación mientras que sílayoutSubviews:
. Nota: estoy usando el diseño automático y iOS 7.0.setFrame:
.frame
es una propiedad derivada. Vea mi respuestaBastante viejo, pero sigue siendo una buena pregunta. En el código de muestra de Apple, y en algunas de sus subclases privadas de UIView, anulan setBounds más o menos como:
Anular
setFrame:
NO es una buena idea.frame
se deriva decenter
,bounds
ytransform
, por lo iOS no necesariamente llamarsetFrame:
.fuente
setBounds:
tampoco se llama al configurar la propiedad del marco (al menos en iOS 7.1). Esta podría ser una optimización que Apple agregó para evitar el mensaje adicional.frame
ybounds
se derivan del subyacente de la vistaCALayer
; simplemente llaman al captador de la capa. YsetFrame:
establece el marco de la capa, mientrassetBounds:
establece los límites de la capa. Por lo tanto, no puede simplemente anular uno u otro. Además,layoutSubviews
se llama en exceso (no solo por cambios de geometría), por lo que tampoco siempre es una buena opción. TodavíaSi está en una instancia de UIViewController, anular
viewDidLayoutSubviews
funciona.fuente
UIView
instancias eUIViewController
instancias. Entonces, si tiene unaUIView
instancia sin VC adjunta, las otras respuestas son excelentes, pero si está adjunto a un VC, este es su hombre. Lo siento, no se aplica a su caso.