UIScrollView no usa restricciones de diseño automático

78

Tengo una vista de desplazamiento y una vista de imagen detrás y la estoy poblando con plumillas. Estoy usando el diseño automático. Tengo un espacio inferior para supervisar y un espacio superior para supervisar ambas vistas. La vista de imagen hace exactamente lo que quiero que haga. Para el iphone 5 está donde lo quiero. Y para los otros iphones, permanece por encima de la parte inferior de la pantalla, por lo que cambia de tamaño correctamente. La vista de desplazamiento se ve bien en el iPhone 5, pero en los otros teléfonos no cambia de tamaño, por lo que se desplaza hacia abajo debajo de la vista de la aplicación. Recibo estos mensajes en el registro:

 2012-11-21 10:42:38.576 LCHApp[12604:907] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want. 
  Try this: (1) look at each constraint and try to figure out which you don't expect;
  (2) find the code that added the unwanted constraint or constraints and fix it.
 (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer
  to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 

"<NSLayoutConstraint:0x1d8ea080 UIScrollView:0x1d8413b0.bottom == UIImageView:0x1d892110.bottom>",
"<NSAutoresizingMaskLayoutConstraint:0x1d8cca10 h=-&- v=-&- ScheduleViewNib:0x1d853630.height == UIScrollView:0x1d8413b0.height - 386>",
"<NSLayoutConstraint:0x1d8e5340 V:[UIImageView:0x1d892110]-(64)-|   (Names: '|':ScheduleView:0x1d8efc30 )>",
"<NSAutoresizingMaskLayoutConstraint:0x1d8cf520 h=--& v=--& V:[ScheduleView:0x1d8efc30(480)]>",
"<NSLayoutConstraint:0x1d8eaed0 V:|-(45)-[UIScrollView:0x1d8413b0]   (Names: '|':ScheduleView:0x1d8efc30 )>"


 Will attempt to recover by breaking constraint 
 <NSLayoutConstraint:0x1d8ea080 UIScrollView:0x1d8413b0.bottom ==      UIImageView:0x1d892110.bottom>

Ya lo intenté

[self setTranslatesAutoresizingMaskIntoConstraints:YES];

y

[self.myScrollView setTranslatesAutoresizingMaskIntoConstraints:YES];

Por lo que puedo ver, esto simplemente elimina todas las restricciones de las vistas. Y no es lo que quiero.

SirRupertIII
fuente
2
La nota técnica TN2154 de Apple: UIScrollView y Autolayout cubre este problema con gran detalle.
smileyborg

Respuestas:

176

La relación entre UIScrollView y el diseño automático es diferente de otros aspectos del diseño automático. Básicamente, si se permitiera que funcionara un diseño automático simple, nada se desplazaría. Por ejemplo, si una subvista de la vista de desplazamiento se fijó de la manera normal mediante una restricción a 10 puntos desde la parte superior de la vista de desplazamiento, se fijaría absolutamente allí; nunca se movería, sin importar cómo se desplazara la vista de desplazamiento.

Para resolver este problema, un UIScrollView que usa autolayout funciona de una manera completamente nueva. Por lo tanto, cuando dice "Estoy usando el diseño automático", debe prepararse para que las cosas funcionen de manera muy diferente a como lo hacía antes. Debe usar una sola subvista de vista de desplazamiento con translatesAutoresizingMaskIntoConstraints = YESy un tamaño de contenido explícito, o de lo contrario todo debe tener translatesAutoresizingMaskIntoConstraints = NOy el tamaño del contenido se deducirá implícitamente en función de las restricciones de las subvistas.

Esto está muy bien explicado en https://developer.apple.com/library/content/releasenotes/General/RN-iOSSDK-6_0/index.html

mate
fuente
5
Puede que le interese esta pregunta: stackoverflow.com/questions/14307037/… (¡sobre todo por la recompensa!) Creo que se trata de un problema de scrollview / autolayout, pero en mi opinión se lee como un error, en este caso el scroll La vista es una vista de tabla y el tamaño del contenido no se ajusta correctamente en la rotación.
jrturton
3
@matt No sé si ha visto este comportamiento, pero si usa solo restricciones de diseño para definir el tamaño del contenido de una vista de desplazamiento, hay un error: desplazar el desplazamiento del contenido desde (0, 0) mover a otra pestaña o controlador de vista modal, regrese y las subvistas de la vista de desplazamiento se desplazarán por el desplazamiento de contenido y no podrá regresar. Le agradecería que pudiera confirmar esto y engañar a mi radar: openradar.appspot.com/radar?id=2932404
edelaney05
3
@ edelaney05 Creo que puedo confirmar el error, pero antes de enviarlo a Apple debería hacer un proyecto de demostración, esp. dado que el código de copiar y pegar en openradar.appspot.com/radar?id=2932404 ni siquiera se compilará (ha escrito el nombre constraintsWithVisualFormat:options:metrics:views:incorrecto). Utilice siempre código real que realmente funcione. Y además, en un proyecto real puedes incluir una imagen real. La gente de Apple no tiene imaginación ni tiempo; debe hacer todo el trabajo por adelantado.
Matt
3
@ edelaney05 "hombro consectetur pancetta" ???? :) Bien. De hecho, hice uno mucho más basado en su código, con una vista de imagen del tamaño de una imagen grande. Al darle a la vista de desplazamiento un color de fondo rojo, y con el registro, estaba muy claro que la vista de desplazamiento pensaba que todo estaba bien (tamaño del contenido, desplazamiento del contenido), pero estaba dibujando la vista de la imagen en el lugar equivocado, es decir, compensada por la cantidad. del contenido desplazado desde que abandonamos la vista.
Matt
2
@matt baconipsum.com ! :-) Increíble. Exactamente el mismo comportamiento que estaba viendo. La vista de desplazamiento informó que todo era "normal", pero el dibujo era incorrecto en un factor del desplazamiento. Gracias por confirmar que no estoy loco (¡pero solo con respecto a este error!).
edelaney05
162

Muy importante cuando se utiliza el diseño automático: debe fijar la parte derecha y / o la parte inferior de la última subvista a la derecha y / o la parte inferior de la vista de desplazamiento. Así es como la vista de desplazamiento conoce el tamaño del contenido. Por ejemplo:

[scrollView addConstraint:[NSLayoutConstraint constraintWithItem:lastSubView
                                                 attribute:NSLayoutAttributeRight
                                                 relatedBy:NSLayoutRelationEqual
                                                    toItem:scrollView
                                                 attribute:NSLayoutAttributeRight
                                                multiplier:1.0
                                                  constant:0]];

Mi agradecimiento a este sitio por proporcionar el ejemplo perfecto.

Perdí horas debido a esto y espero ahorrarles a otros mi dolor.

phatmann
fuente
4
Esto es perfecto. He estado buscando un ejemplo simple como el del enlace. ¡¡¡Gracias!!!
pgpb.padilla
Si bien la respuesta de mate es bueno, éste es mucho más práctica útil para la solución de los problemas que he tenido con usarlo
dmur
22
@dmur "Si bien la respuesta de Matt es buena, esta es mucho más útil en la práctica". Amigo, esta también es mi respuesta. ¡Obtuvo el código / explicación de mi libro! Me alegro de haber podido ayudar dos veces. :)))
Matt
Dependiendo de cómo diseñe su scrollView y sus subvistas, es posible que deba fijar sus cosas a la izquierda o arriba. En mi caso, tuve que fijar todo a la izquierda.
ArtSabintsev
También puede agregar la restricción a través de Interface Builder. ¡Gran respuesta!
Moisés Olmedo
0

Para que UIScrollviews funcione bien con las restricciones, utilizo este enfoque que se responde aquí . En esa respuesta, abordo cómo hacer que funcione una vista de desplazamiento de desplazamiento vertical que también funcione con la rotación del dispositivo. También puede modificar el enfoque para trabajar con vistas de desplazamiento de desplazamiento horizontal . Para las vistas de desplazamiento que se desplazan en ambas direcciones, no agregue el truco de restricción de ancho de coincidencia de tamaño. Pero haz todo lo demás igual.

n8tr
fuente
-3

Un par de cosas.

  1. asegúrese de que el diseño automático esté activado (IB en la "pestaña Inspector de archivos")
  2. Asegúrese de NO realizar ningún cambio que implique límites, marcos, etc. - todo esto se realiza ahora mediante restricciones automáticas
  3. Asegúrese de mantenerse alejado de AutoResizingMask. Esto competirá con su nueva configuración. Si se hace bien, ahora puede diseñar su botón y funcionará muy bien. Así es cómo.

Este error indica que su plumilla o un control dentro de esa plumilla NO está usando el diseño automático.

JustLearningAgain
fuente
1
Pero UIScrollView es especial y su respuesta no tiene en cuenta ese hecho.
Matt