Interface Builder: ¿Cuáles son los layouts de UIView's iOS 6/7 Deltas?

Acabo de notar la propiedad iOS 6/7 Delta que se encuentra bajo el layout de estructuras de UIView.

¿Para qué sirve esto y por qué falta en AutoLayout?

introduzca la descripción de la imagen aquí

Esto realmente se refiere al delta entre la position de layout de iOS6 a iOS7.

En iOS7, algunas vistas pueden ocultar la barra de estado o hacer que sea transparente y, en efecto, se superpone en la parte superior de su vista. Por lo tanto, si coloca un elemento de interfaz de usuario en (0.0, 0.0) en iOS6, aparecerá debajo de la barra de estado, pero en iOS7 aparecerá parcialmente cubierto debajo de la barra de estado. Entonces, en ese caso, querrá un delta que coincida con la altura de la barra de estado (20.0 puntos) para que el layout se vea igual en iOS6 e iOS7.

Creo que esto no es necesario si utilizas la reproducción automática, pero, por supuesto, pierdes el soporte iPad1, que muchos de nosotros no estamos dispuestos a aceptar en este momento.

Nota: noté esta pregunta hace un time, pero solo estoy publicando mi respuesta ahora porque la NDA se ha levantado

¿Por qué no aparece para AutoLayout?

Como habrás notado, iOS 7 ofrece un aspecto completamente nuevo. El aspecto de los elementos de la interfaz de usuario ha cambiado, pero también tienen algunos de sus tamaños (o métricas en general). Esto puede hacer que el layout de la interfaz admita tanto a iOS 7 como a sus pnetworkingecesores un poco de dolor.

La línea oficial de Apple es utilizar AutoLayout para resolver esto; esto debería tomar una gran parte de la molestia de trazar los elementos de la interfaz de usuario para usted. A veces, incorporar esto no es fácil, especialmente si aún debe admitir iOS 5 por motivos comerciales o si sus interfaces se gestionan de forma tal que dificulte la implementación de AutoLayout. Como tal, Apple parece haber proporcionado una forma de hacer que su trabajo sea un poco más fácil si se incluye en esta categoría de nicho, y llamaron a este iOS 6/7 Deltas.

Ok entonces, ¿qué hace?

Si bien la label de Interface Builder no está clara con respecto a lo que significa 'Delta' en este context, el código contenido en el file .xib que corresponde a esta característica es un poco más claro:

<inset key="insetFor6xAndEarlier" minX="-50" minY="-100" maxX="-50" maxY="300"/>

El nombre de key insetFor6xAndEarlier explícitamente indica lo que esto hace; puede proporcionar inserciones alternativas para elementos de interfaz de usuario cuando se ejecutan en los pnetworkingecesores de iOS 7. Por ejemplo, lo anterior define el siguiente cambio delta:

 x: 50 y: 100 width: -100 height: 200 

Si bien los valores almacenados en el .xib no corresponden a los valores cotizados directamente, existe una correlación entre ellos.

 x: -minX y: -minY width: minX + maxX height: minY + maxY 

Las imágenes a continuación muestran este cambio visualmente. Es un ejemplo extremo, pero es para demostrar su habilidad. Solo espero que en la práctica se tengan cambios delta de solo unos pocos píxeles.

Vista de iOS7

Vista de iOS6

Puede observar que los valores son inversos para la vista de iOS 6; esto se debe a que los deltas son relativos al tipo de vista con la que está trabajando. Si está editando para iOS 6, los deltas existen para transformar el elemento correctamente para iOS 7 (al revés del ejemplo anterior).

Para ver los diferentes styles, puede cambiar la forma en que Interface Builder lo presenta en function del sistema operativo en el que se ejecutaría. Esto está contenido en el Inspector de files-> Documento de generador de interfaces (1ª pestaña en la barra derecha), como tal:

Interruptor de estilo de interfaz

¿Esto existe si me gusta codificar mi interfaz a mano?

No directamente, pero puede lograr fácilmente el mismo efecto al tener comprobaciones condicionales en la versión del sistema operativo dentro de su código, y establecer la position / tamaño correcto en consecuencia. La capacidad delta existe en Interface Builder porque no habría una forma directa de tener un posicionamiento condicional sin tener código para hacerlo, y el punto de Interface Builder es get un código mucho más alejado del path posible para la interfaz de usuario.

En general…

Apple recomienda enfáticamente que uses AutoLayout, te hace la vida más fácil en la mayoría de los casos. Si no puede usarlo (por las razones mencionadas anteriormente), los deltas le brindan la flexibilidad para ubicar sus elementos de interfaz de usuario de manera adecuada, en function de las métricas del sistema operativo actual, sin necesidad de volver a colocarlos manualmente en el código. Un buen ejemplo es ajustar por la falta de barra de estado, pero hay muchos otros casos de uso.

Naturalmente, si solo está desarrollando para iOS7 o superior, no necesita saber esta característica / no la descubrirá. Solo si necesita tener dispositivos iOS6 que ejecuten su aplicación cuando se construye con el SDK de iOS7, sin autolayout, ¿necesita deltas?

En el momento de la networkingacción (21 de agosto), no puedo encontrar ninguna documentation sobre esta característica, ni ninguna mención en el material de WWDC. He tenido un juego, y después de un poco de investigación, eso es lo que he descubierto.

Sé que esto ya ha sido respondido, simplemente agregando una pequeña variante con la esperanza de que también podría ayudar a aquellos que no usan la function de layout automático y aún quieren soportar iOS 6.1 y versiones anteriores.

Lea esta Guía de transición de Apple: versión anterior compatible

Elija 'Ver como' a 'iOS 7.0 y posteriores'

introduzca la descripción de la imagen aquí

Base de UI para iOS 7. Para iOS 6, dé el valor delta adecuado. Use la vista previa para ver cómo se renderizará en el dispositivo iOS 7 y iOS 6.

introduzca la descripción de la imagen aquí

Pasos rápidos:

Seleccione cada hijo inmediato de la vista raíz individualmente y agregue 20px a su valor 'Y'.

introduzca la descripción de la imagen aquí

Luego, select todos los niños inmediatos colectivamente y dé delta Y como -20px. También puede hacerlo de forma individual o por lotes.

introduzca la descripción de la imagen aquí

AutoLayout requiere al less iOS 6.0. Si desea admitir iOS 5.0, no puede usar AutoLayout.

Y esos deltas se utilizan para ayudarlo a ajustar la position de la vista en diferentes versiones de iOS (principalmente iOS 7 e iOS versión inferior a 7).

Utilizo esos valores para ayudarme a esta image. introduzca la descripción de la imagen aquí

Para ver iOS 6/7 Delta en acción, haré una demostración con un SegmentedControl que aparece correctamente en dispositivos iOS 6 e iOS 7.

Primero, select su .Xib o ViewController en Storyboard. Desmarca Usar Autolayout y selecciona " Ver como iOS 7 y posterior "

introduzca la descripción de la imagen aquí

En el canvas de Interface Builder, coloque su SegmentedControl para que su origen sea ​​20. En iOS 6/7 Delta, elija -20 para DeltaY

introduzca la descripción de la imagen aquí

Esto hará que su SegmentedControl esté por debajo de la barra de estado tanto en dispositivos iOS 6 como iOS 7

introduzca la descripción de la imagen aquíintroduzca la descripción de la imagen aquí

Otras citas útiles de la Guía del desarrollador para iOS 7 Barra de estado

Los Deltas se pueden configurar individualmente para cada vista y funcionan como cabría esperar. Si su guión gráfico o plumilla está configurado para visualizarse como iOS 6, la configuration de los deltas hará que esa vista sea desplazada y / o networkingimensionada por el monto delta configurado cuando se ejecute en iOS 7. Alternativamente, si su guión gráfico o plumilla está configurado para verlo en iOS 7, los deltas se aplicarán cuando se ejecuten en iOS 6

Si está utilizando AutoLayout, Delta no está disponible. Prueba esto (probado en iPhone 4s con iOS6):

 - (void) viewWillLayoutSubviews { //iOS 6 workaround offset if ([[[UIDevice currentDevice] systemVersion] floatValue] < 7) { self.view.clipsToBounds = YES; CGRect screenRect = [[UIScreen mainScreen] bounds]; CGFloat screenHeight = 0.0; screenHeight = screenRect.size.width; CGRect screenFrame = CGRectMake(0, -20, self.view.frame.size.width,self.view.frame.size.height+10); self.view.frame = screenFrame; } }