Diseño automático está haciendo la vida difícil. En teoría, iba a ser muy útil cuando me cambié, pero me parece que luchar todo el tiempo.

He hecho un proyecto de demostración para tratar de encontrar ayuda. ¿Alguien sabe cómo hacer que los espacios entre los puntos de vista de aumentar o disminuir de manera uniforme siempre que la vista cambia de tamaño?

Aquí hay tres etiquetas (manualmente espaciados verticalmente incluso):

Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

Lo que yo quiero es para ellos para cambiar el tamaño de su espacio (no del tamaño de la vista) de manera uniforme cuando me gire. Por defecto, la parte superior e inferior de las vistas aplastar hacia el centro:

Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

  • tal vez establecido la restricción de una etiqueta a otra, y les relación «mayor o igual que» va a ser útil
  • mediante programación, por ejemplo, con el uso de este método de NSLayoutConstraint: + (id)constraintWithItem:(id)vista1 atributo:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relación toItem:(id)view2 atributo:(NSLayoutAttribute)attr2 multiplicador:(CGFloat)multiplicador constante:(CGFloat)c
  • Yo abrimos un genérico UITabBar de reemplazo que generaliza este enfoque utiliza la función de Diseño. Usted puede comprobar a cabo las pruebas para ver cómo puedo generar mi Auto restricciones de Diseño. GGTabBar
InformationsquelleAutor nothappybob | 2012-10-25

28 Comentarios

  1. 206

    Así que mi enfoque permite hacer esto en el interface builder. Lo que tienes que hacer es crear «espaciador vistas» que se han ajustado para que coincida con alturas igualmente. A continuación, agregue la parte superior e inferior de las restricciones a las etiquetas (consulte la captura de pantalla).

    Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

    Más específicamente, tengo los mejores restricción en ‘Espaciador de Vista 1’ a superview, con una altura de restricción de prioridad inferior a 1000 y con la Altura es Igual a todos los demás «espaciador de vistas». ‘Espaciador 4 de la Vista’ tiene un espacio inferior restricción de superview. Cada etiqueta tiene una parte superior y la parte inferior restricciones a su más cercano espaciador vistas».

    Nota: asegúrese de que NO tiene exceso de la parte superior/inferior de las limitaciones de espacio en las etiquetas para superview; sólo aquellas a la espacio de los puntos de vista’. Esto será válido desde la parte superior y la parte inferior restricciones en el Espacio de la Vista 1′ y ‘Espaciador 4 de la Vista’, respectivamente.

    Duh 1: he duplicado mi punto de vista y simplemente ponerlo en modo horizontal, por lo que podía ver que funcionaba.

    Duh 2: El espaciador vistas’ podría haber sido transparente.

    Duh 3: Este enfoque podría aplicarse horizontalmente.

    • Esto funciona. De hecho espaciador de las vistas se puede oculto y que van a producir el diseño correcto.
    • Esto era muy útil. Como fue el comentario acerca de que acaba de marcar el espaciador vistas como oculto. A continuación, puede ver todavía en su guión gráfico/xib, pero que no se muestran en la aplicación. Muy bonito.
    • Yo tengo casi de trabajo después de varias horas de intentos repetidos. Por desgracia Xcode mantiene la eliminación de mi top-espacio-para-botón de abajo de las limitaciones de espacio, rompiendo la cadena entre los botones y separadores, y su sustitución por arbitraria superior-espacio-para-superview restricciones, que son inútiles.
    • El mismo enfoque funciona para mí en disposición horizontal – he de ancho fijo vistas separadas por la igualdad de ancho espaciador vistas. Es genial que no necesito mezclarlo con ningún código. Gracias!
    • Gracias! He revisado este problema en un nuevo proyecto y se han encontrado para ser más exacta la solución a mi problema. Además tiene la ventaja de estar completamente en el interface builder.
    • No hay necesidad de utilizar espaciadores. Véase mi respuesta a continuación.
    • el uso de los espaciadores es demasiado complicado. Véase mi respuesta a continuación, utilizando los multiplicadores. stackoverflow.com/questions/13075415/…
    • Tengo un caso con 4 etiquetas y 5 espaciador de puntos de vista y no funciona. Todo es perfecto hasta que me haga la anchos iguales conexión con el Espaciador de Vista 1 y Último Espaciador de Vista, yo estoy poniendo restricción de errores
    • la respuesta perfecta..! muchas gracias
    • Dar StackViews una prueba (véase el Glorfindel de la respuesta) antes de sumergirse en estos enfoques más complejos.

  2. 312

    MIRA, NO ESPACIADORES!

    Basándose en las sugerencias en la sección de comentarios de mi respuesta original, especialmente @Rivera sugerencias útiles, he simplificado mi respuesta original.

    Estoy usando gifs para ilustrar lo sencillo que es esto. Espero que usted encuentre los gifs útil. En caso de tener un problema con los gifs, he incluido la vieja respuesta de abajo con un simple capturas de pantalla.

    Instrucciones:

    1) Agregar los botones o etiquetas. Estoy usando 3 botones.

    2) Agregar un centro x restricción de cada uno de los botones para el superview:

    Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

    3) Agregar una restricción de cada botón en la parte inferior de diseño de restricción:

    Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

    4) Ajustar la restricción añadida en el #3 de la siguiente manera:

    a) seleccione la restricción,
    b) quitar la constante (0),
    c) cambiar el multiplicador de la siguiente manera: tome el número de botones de + 1, y comenzando por la parte superior, establecer el multiplicador como buttonCountPlus1:1 y, a continuación, buttonCountPlus1:2, y finalmente buttonCountPlus1:3. (Explico de dónde saqué esta fórmula de en la vieja respuesta de abajo, si te interesa).

    Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

    5) Aquí una demo corriendo!

    Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

    Nota: Si los botones tienen grandes alturas, a continuación, tendrá que compensar esta en el valor constante ya que la restricción de la parte inferior del botón.


    Respuesta Anterior


    A pesar de lo que Apple docs y Erica Sadun del excelente libro (Diseño Automático Desmitificado) decir, es posible de manera uniforme las vistas de espacio sin espaciadores. Esto es muy simple de hacer en IB y en el código para cualquier número de elementos que desea el espacio de manera uniforme. Todo lo que necesitas es una fórmula matemática llamada la «fórmula de sección». Es más sencillo de hacer que de explicar. Voy a hacer mi mejor esfuerzo por demostrar que en IB, pero es igual de fácil de hacer en el código.

    En el ejemplo en cuestión, tendría que

    1) empezar por la creación de cada etiqueta para tener un centro de restricción. Esto es muy simple de hacer. Simplemente arrastre de control de cada etiqueta en la parte inferior.

    2) Mantenga presionada la tecla mayús, ya que podría también agregar la otra restricción que vamos a utilizar, es decir, el «espacio inferior a fondo guía de diseño».

    3) Seleccione el «espacio inferior a fondo guía de diseño», y «centro horizontalmente en un contenedor». Hacer esto para todas las 3 etiquetas.

    Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

    Básicamente, si tomamos la etiqueta cuyas coordenadas queremos determinar y se divide por el número total de etiquetas más 1, entonces tenemos un número que se le pueden añadir a la IB para obtener la dinámica de la ubicación. Estoy simplificando la fórmula, pero que se podría utilizar para la configuración de espaciado horizontal o en vertical y horizontal al mismo tiempo. Es super potente!

    Aquí están nuestros multiplicadores.

    Label1 = 1/4 = .25,

    Label2 = 2/4 = .5,

    Label3 = 3/4 = .75

    (Edit: @Rivera comentó que usted puede utilizar simplemente las proporciones directamente en el campo del multiplicador, y xCode con hacer las matemáticas!)

    4) Así que, vamos a seleccionar Label1 y seleccione la parte inferior de la restricción. Como este:
    Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

    5) Seleccione el «Segundo Elemento» en los Atributos del Inspector.

    6) Desde el menú desplegable, selecciona «Invertir primer y segundo elemento».

    7) puesta a Cero de la constante y el wC hAny valor. (Usted puede añadir un offset aquí si usted lo necesita).

    8) Esta es la parte crítica: En el campo de multiplicador de añadir nuestro primer multiplicador de 0.25.

    9), Mientras que usted está en el top de «Primer elemento» a «CenterY» ya que queremos centrar a la etiqueta y del centro. He aquí cómo todo lo que debe buscar.

    Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

    10) Repita este proceso para cada etiqueta y tapón en el correspondiente multiplicador: 0,5 para Label2, y de 0,75 para la Label3. Aquí está el producto final en todas las orientaciones con todos los compactos dispositivos! Super simple. He estado mirando un montón de soluciones que involucran a páginas y páginas de código, y los espaciadores. Este es, de lejos, la mejor solución que he visto sobre el tema.

    Actualización: @kraftydevil agrega que la parte Inferior guía de diseño que sólo aparecen en los storyboards, no en xibs. El uso de ‘Espacio Inferior para Contenedor’ en xibs. Buena captura!

    Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

    • Que versión de Xcode? 6?
    • Me pregunto porque no puedo encontrar la restricción de menú en el #4 (Primer Elemento, el Segundo Elemento, de Relación, etc) después de hacer los pasos anteriores. Después de elegir el tamaño de inspector, todo lo que veo son los siguientes submenús: la Vista, el Contenido Abrazos Prioridad, Contenido de la Resistencia a la Compresión de Prioridad y Limitaciones de
    • mi error fue que no me doy cuenta de que podría encontrar la restricción en el Esquema del Documento. #5 debe ser ‘Atributos’ inspector. Es originalmente el nombre de «Espacio Vertical».
    • He cambiado a «los Atributos del Inspector». Mi mal. Hizo el trabajo para usted? Esto me parece muy potente. He resuelto bastante complejo diseño utilizando este. No se necesitan espaciadores.
    • Todavía estoy luchando con él. Creo que debe ser el uso de Xcode 6, debido a que no existe un ‘wC hAny’ opción en Xcode 5 restricciones. Cuando yo siga sus instrucciones, todas las subvistas quedas atascado de la parte central superior.
    • AFAIK Inferior de la guía de diseño que sólo aparecen en los storyboards, no en xibs. El uso de ‘Espacio Inferior para Contenedor’ en xibs.
    • Voy a añadir que a la respuesta. Yo rara vez uso de puntas de modo que no era consciente de esto.
    • Gracias @cocoanut se tomó un tiempo para entenderlo, pero al final lo he conseguido. Gracias gracias. Usted salvó mi día!!!!!
    • Genial! Gracias por este trabajo a cabo. Ahora puedo dejar de usar el tedioso vistas anidadas método.
    • Me alegro de que te ayudó a salir. Gracias por decir así.
    • Me gusta este enfoque. Por sí mismas, no hacen la vista exprimir si no caben todos (imagino que con lo de la plaza de botones largo de la anchura de una pantalla). Sin embargo, debe ser fácil también limitar la vista de anchura no será más que available-width / number-of-views
    • Oh – también vale la pena señalar que el IB en Xcode 6 es compatible con la relación de los multiplicadores, así que usted puede poner en cosas como «1:4», «2:5», «3:4», etc.
    • Voy a echarle un vistazo.
    • Toma un par de ensayos para realmente entender lo que está ocurriendo aquí, pero este es, por lejos, el mejor método que he visto!
    • La misma idea puede ser traducido para el formato visual de la lengua también. 🙂
    • Perfecto! Esta es una solución mucho mejor que la » cadena de la igualdad de espaciador vistas a la técnica, que siempre me da problemas con el complejo interdependiente restricción de prioridades. Gracias por señalar cómo la parte inferior guía de diseño puede ser utilizado en conjunción con la posición de la restricción de los multiplicadores.
    • Tratando de averiguar cómo hacer esto de forma horizontal como primer TextView 1/3 del camino de la izquierda, y un segundo TextView 2/3 (resto del camino)… …(EDITAR) consiguió hacer el primer 1/3 (el de la izquierda) Finales-Espacio para el Margen Derecho, a la inversa, cero, asignar como antes…
    • Me gusta esta mejor en principio, pero no puede hacer que funcione en una subvista. Multiplicador de no tomar un número decimal (vuelve a 1) y las fracciones no producen los resultados esperados.
    • No tengo idea de cómo o por qué esto funciona, pero la respuesta a esto es increíble! Si había una manera de dar algún tipo de recompensa me gustaría! Gracias! 🙂
    • He utilizado la fórmula de sección. Aquí está el cero notas si usted está interesado evernote.com/shard/s28/sh/ecd21f8d-1cc5-4059-ab15-54fd75fce9bc/…
    • Esta respuesta debe ser marcada como la respuesta correcta. La primera vez que utiliza el método que está marcada como correcta originalmente y, finalmente, se quedó en los principales problemas a la hora de animar. Este método es mucho más eficiente e intuitiva.
    • su respuesta es por lejos el mejor aquí (a pesar de que el espaciador métodos funciona muy bien). Simplemente, me encantó 😉 Deseo de que hay una manera de ponerlo como el mejor 😉
    • En realidad, la proporción es de una gran sugerencia! Y sí, el tamaño de las clases no tienen que ver con este. Me acaba de pasar a estar en compacto de ancho. ¿He dicho algo engañosa?
    • Nada engañoso realmente, solo que he visto tantos errores últimamente debido al Tamaño de las Clases de uso indebido.
    • También el paso 6 no es necesario, simplemente la inversa de la relación de 3:4 -> 4:3.
    • no creo que esto funciona como el OP quiere, cuando usted hace ratios de no hacer la misma como el uso de espaciadores. con proporciones habrá más espacio entre el borde de las etiquetas. Con espaciadores el espacio es igual entre las etiquetas y las fronteras
    • Asegúrese de que usted no está correspondientes a la parte superior guía de diseño. Si quieres un espaciado uniforme, incluyendo márgenes adjuntar a la superview lugar.
    • Se está trabajando para mí no hay ningún problema con 50×50 botones. Acabo de hacer un proyecto de scratch. Asegúrese de dar a los botones de una altura y anchura. La otra cosa es recordar que siempre se puede ajustar la constante, si es necesario.
    • divertido. Para mí no funciona.
    • ¿Qué pasa si el término medio es un scrollview nd quiero su altura para crecer un poco más(altura actual es de 20, pero puede ser <= 40) como el dispositivo aumenta la altura?
    • también puede responder aquí: stackoverflow.com/q/30283815/1364053
    • Estas soluciones no funcionan conmigo porque solicitud de apoyo árabe & Idioma inglés . ¿Esta solución admite RTL & LTR?
    • No veo por qué no. Puede usted explicar el asunto un poco más en detalle. Son capaces de obtener los LITROS de la versión de trabajo?
    • Ivaniushchenko creo que el caso en que aumenta el botón de alturas en los comentarios de 11 de Mayo. Check it out.
    • Sí, pero es que no es posible hacer nada con las vistas que utilizan intrínseca tamaño del contenido en IB-la única solución, por lo que espaciador vistas son la mejor solución en este caso y estas 2 soluciones no son iguales
    • Alguien ha tenido suerte de llegar a este para trabajar con elementos de espaciado en una subvista? Lo he probado, y funciona cuando los botones están en la raíz de la vista, pero cuando mi diseño, requiere que los botones estén en una subvista, y no parece cambiar el modificador hace nada en ese momento.
    • ¿Por qué haber ningún problema usando intrínsecas tamaño del contenido? El 11 de mayo me dan la respuesta de cómo adaptarse a los botones más grandes. Yo lo he probado. Funciona.
    • De todos modos, esta solución no funciona con longitud variable textos localizados
    • Cómo hacerlo mediante programación? He estado tratando de reproducir sin suerte.
    • Puedo seguir este tutorial para el espaciamiento horizontal youtube.com/watch?v=WTMpJJ9Ofm8
    • bonita respuesta, gracias @smileBot
    • Se puede hacer esto si los botones/etiquetas tienen anchos diferentes? Yo lo he probado y hace que el espacio fuera un poco. Alguna sugerencia?
    • ¿te refieres a diferentes alturas? Compruebe el 11 de Mayo de comentario.
    • no, me refiero a diferentes anchos.
    • Para el espaciamiento horizontal, simplemente tirados restricciones a la superview para cada subvista, y, a continuación, establezca el coeficiente multiplicador por ejemplo. 5:1, 5:2, 5:3, etc. se mueve de izquierda a derecha.
    • esta es una deliciosa y bien organizado respuesta. respecto a su comentario sobre las personas que tienen problemas con los gifs… la razón gif persiste así indefinidamente es que es el mínimo común denominador de las cosas animadas en la web. siempre funciona para todos de una muy buena aproximación. 🙂 gracias por sus esfuerzos. 🙂
    • La razón por la que hice el comentario acerca de los gifs es que una vez había alguien voto porque me incluidos los gifs. Creo que era un troll cosa.
    • Esta solución sólo funciona para un número impar de puntos de vista. Ver Mete la respuesta de abajo para una fórmula que funciona con pares e impares número de vistas de espacio.
    • Dar StackViews una prueba (véase el Glorfindel de la respuesta) antes de sumergirse en estos enfoques más complejos.
    • esto debería fallar con RTL árabe
    • No creo RTL importa en este caso. Pero en estos días usted debe utilizar stackviews. Esta solución es anterior a stackviews.
    • Muchas gracias…me ayudo..:) Después de mucho tiempo aprendí la técnica para dar vertical incluso espacios 🙂
    • Este es un hack. Tirar en otro control, y usted tiene que volver a calcular la distancia que es el punto entero de Autodiseño. Así que con una demo que sí se ve bien. En la vida real esto es un desastre.
    • Usted debe estar utilizando stackviews estos días, a menos que usted no puede, por alguna razón. Esta manera de hacerlo no es necesario.

  3. 93

    Muy rápida de la Interfaz del Generador de solución:

    Para cualquier número de puntos de vista para ser espaciados uniformemente dentro de un superview, simplemente dar a cada uno un «Alinear en el Centro X a superview» restricción para la distribución horizontal, o «Alinear en el Centro Y superview» para el diseño vertical, y establecer el Multiplicador para ser N:p (NOTA: algunos han tenido mejor suerte con p:N – ver más abajo)

    donde

    N = total number of views, y

    p = position of the view including spaces

    Primera posición es 1, seguido de un espacio, haciendo la siguiente posición 3, entonces p se convierte en una serie [1,3,5,7,9,…]. Funciona para cualquier número de puntos de vista.

    Por lo tanto, si usted tiene 3 vistas al espacio, se ve como esto:

    Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

    EDITAR Nota: La elección de N:p o p:N depende de la relación de orden de su alineación de restricción. Si «Primer Elemento» es Superview.Centro, usted puede usar p:N, mientras que si Superview.El centro es «la Segunda», usted puede utilizar N:p. En caso de duda, acabo de probar los dos… 🙂

    • Respuesta correcta hasta que Apple construye una solución específica
    • Increíble respuesta. Un poco de sentido común aplicadas a las coordenadas y elementos para alinear.
    • Así de simple!!! Gracias!
    • Esta solución no va a reflejar el diseño si usted cambia a otro idioma
    • ¿A qué te refieres? Interruptor de qué otro idioma? Y lo que rompe exactamente?
    • ¿y si los elementos no son del mismo tamaño? este patrón no funciona correctamente?
    • todos ellos estarán centrados en los lugares adecuados, seguro. Si usted quiere que ellos tienen diferentes dimensiones, pero la misma cantidad de espacio de borde a borde, usted tendrá que hacerlo de una manera diferente, por supuesto!
    • Es una correcta y mejor solución, probé con diferentes elementos de la anchura. Es muy sencillo y de trabajo!
    • lo que si tengo 4 botones? ¿Cómo puedo espacio de los botones?
    • No entiendo cómo esta solución es la correcta? El espacio entre el borde de la pantalla y elementos exteriores es diferente a la brecha entre los elementos exteriores y el centro de elemento?
    • la respuesta es genérico, sólo se aplica a los 4 elementos del caso.
    • Funciona antes de iOS9. Respuesta correcta, pero si chanle número de artículos – te sientes a ti mismo triste((.
    • Esto funcionó para mí mientras @smilebot la respuesta no. No sé por qué.
    • No consigo que funcione con dos elemtents, utilizando para multiplicador de 2:1 para el primer elemento y 2:3 para el segundo.
    • Esto no es para mí «como es» tuve que invertir los multiplicadores (ej. el 3:1 en el primer elemento se convierte en 1:3). Acaba de lanzar esto si ayuda a alguien.
    • editado para explicar por qué algunas personas tienen para revertir el multiplicador.
    • Gracias por la buena respuesta, que funciona muy bien en iOS10. Sí, sólo por otros de referencia, tengo 4 botones. Y la relación que estoy usando son: 1/4, 3/4, 5/4, 7/4. Funciona como un encanto! Estoy sorprendido de cómo Apple hace que todo sea tan complicado para la interfaz de usuario de cosas, lol.
    • Dar StackViews una prueba (véase el Glorfindel de la respuesta) antes de sumergirse en estos enfoques más complejos.
    • Gracias, me siento más sana ahora. 🙂
    • Muy bien explicado y funciona de maravilla. Gracias por esta solución Mete!

  4. 66

    Como de iOS 9, Apple ha hecho que esta muy fácil con la (esperada) UIStackView. Simplemente seleccione las vistas que desea que contenga en el Interface Builder y elija Editor -> Incrustar En -> Pila de vista. Ajustar la anchura/altura/margen de las restricciones para la pila de vista, y asegúrese de establecer la Distribución de la propiedad de la Igualdad de espaciado’:

    Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

    Por supuesto, si necesita compatibilidad con iOS 8 o inferior, tendrás que elegir una de las otras opciones.

    • Awersome!! Exactamente lo que estoy buscando! Gracias mucho!
    • Sí, Es triste que esto no tiene retro compatibilidad, así que hasta que la aplicación necesita de apoyo para IOS8 @Mete respuesta es la mejor por ahora.
    • Viniendo de Android yo estaba luchando con esto por un buen rato. Luego me enteré de Pila de Vista!
  5. 50

    He estado en una montaña rusa de amar autodiseño y lo odia. La clave para amar parece ser la de aceptar los siguientes:

    1. Generador de interfaz de edición y «útil» auto-creación de limitaciones a que está cerca de inútil para todos, pero los casos más triviales
    2. La creación de categorías para simplificar las operaciones más comunes es un salvavidas puesto que el código es tan repetitiva y detallado.

    Que dijo, lo que se intenta no es tan sencillo y sería difícil de lograr en el interface builder. Es muy simple de hacer en el código. Este código, en viewDidLoad, crea y coloca tres etiquetas de cómo se están pidiendo para ellos:

    //Create three labels, turning off the default constraints applied to views created in code
    UILabel *label1 = [UILabel new];
    label1.translatesAutoresizingMaskIntoConstraints = NO;
    label1.text = @"Label 1";
    UILabel *label2 = [UILabel new];
    label2.translatesAutoresizingMaskIntoConstraints = NO;
    label2.text = @"Label 2";
    UILabel *label3 = [UILabel new];
    label3.translatesAutoresizingMaskIntoConstraints = NO;
    label3.text = @"Label 3";
    //Add them all to the view
    [self.view addSubview:label1];
    [self.view addSubview:label2];
    [self.view addSubview:label3];
    //Center them all horizontally
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:label1 attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0]];
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:label2 attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0]];
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:label3 attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0]];
    //Center the middle one vertically
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:label2 attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0]];
    //Position the top one half way up
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:label1 attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:label2 attribute:NSLayoutAttributeCenterY multiplier:0.5 constant:0]];
    //Position the bottom one half way down
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:label3 attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:label2 attribute:NSLayoutAttributeCenterY multiplier:1.5 constant:0]];

    Como digo, este código se simplifica mucho con un par de categoría de métodos en UIView, pero para mayor claridad he hecho el largo camino de aquí.

    La categoría es aquí para los interesados, y tiene un método para distancias iguales a una matriz de puntos de vista a lo largo de un eje determinado.

    • Usted señor, es un salvavidas. Yo no entendía #1 hasta ahora. Interface builder, me está volviendo loco, pero pensé que era capaz de hacer todas las cosas de la misma. Yo prefiero usar el código de todos modos, así que esto es perfecto, y me pongo en la categoría de métodos.
    • Sería la publicación de su recomendado código de la categoría?
    • aquí vamos: github.com/jrturton/UIView-Autolayout
    • A pesar de que es bastante cercana, esto no acaba de resolver el problema exacto frecuentes (manteniendo la vista del tamaño de la misma con un espaciado uniforme entre subvistas). Esta solución es el refinado caso general de respuesta.
    • Dar StackViews una prueba (véase el Glorfindel de la respuesta) antes de sumergirse en estos enfoques más complejos.
  6. 20

    La mayoría de estas soluciones depende de que exista un número impar de elementos, de modo que usted puede tomar el medio punto y el centro de la misma. ¿Qué hacer si tiene un número par de artículos que usted todavía desea ser distribuido uniformemente? He aquí una solución más general. En esta categoría se va a distribuir de manera uniforme en cualquier número de elementos a lo largo del eje horizontal o vertical.

    Ejemplo de uso para distribuir verticalmente 4 etiquetas dentro de su superview:

    [self.view addConstraints:
    [NSLayoutConstraint constraintsForEvenDistributionOfItems:@[label1, label2, label3, label4]
    relativeToCenterOfItem:self.view
    vertically:YES]];

    NSLayoutConstraint+EvenDistribution.h

    @interface NSLayoutConstraint (EvenDistribution)
    /**
    * Returns constraints that will cause a set of views to be evenly distributed horizontally
    * or vertically relative to the center of another item. This is used to maintain an even
    * distribution of subviews even when the superview is resized.
    */
    + (NSArray *) constraintsForEvenDistributionOfItems:(NSArray *)views
    relativeToCenterOfItem:(id)toView
    vertically:(BOOL)vertically;
    @end

    NSLayoutConstraint+EvenDistribution.m

    @implementation NSLayoutConstraint (EvenDistribution)
    +(NSArray *)constraintsForEvenDistributionOfItems:(NSArray *)views
    relativeToCenterOfItem:(id)toView vertically:(BOOL)vertically
    {
    NSMutableArray *constraints = [NSMutableArray new];
    NSLayoutAttribute attr = vertically ? NSLayoutAttributeCenterY : NSLayoutAttributeCenterX;
    for (NSUInteger i = 0; i < [views count]; i++) {
    id view = views[i];
    CGFloat multiplier = (2*i + 2) / (CGFloat)([views count] + 1);
    NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:view
    attribute:attr
    relatedBy:NSLayoutRelationEqual
    toItem:toView
    attribute:attr
    multiplier:multiplier
    constant:0];
    [constraints addObject:constraint];
    }
    return constraints;
    }
    @end
    • Se trabajó mediante la eliminación de todas las restricciones e inmediatamente después, añadir la Anchura y la Altura de las restricciones a los objetos, a continuación, llamar el método constraintsForEvenDistributionOfitems:relativeToCenterOfItem:vertical:
    • Me encantaría ver tu código, porque cuando trato con un número par de elementos de este código funciona perfectamente cuando el dispositivo de conmutación de orientaciones. Está usted seguro de que no sin querer tener algunas otras limitaciones (como la autoresizing restricciones) que están causando un conflicto?
    • He aquí un ejemplo de la creación de 4 etiquetas y uniformemente espaciado a lo largo del eje vertical: gist.github.com/bdolman/5379465
  7. 17

    Echa un vistazo a la librería de código libre PureLayout. Ofrece un par de métodos de la API para la distribución de puntos de vista, incluyendo variantes donde el espaciado entre cada punto de vista es fijo (ver el tamaño varía según sea necesario), y donde el tamaño de cada punto de vista es fijo (espaciado entre los puntos de vista varía según sea necesario). Tenga en cuenta que todos estos se realizan sin el uso de cualquier «espaciador de puntos de vista».

    De NSArray+PureLayout.h:

    //NSArray+PureLayout.h
    //...
    /** Distributes the views in this array equally along the selected axis in their superview. Views will be the same size (variable) in the dimension along the axis and will have spacing (fixed) between them. */
    - (NSArray *)autoDistributeViewsAlongAxis:(ALAxis)axis
    alignedTo:(ALAttribute)alignment
    withFixedSpacing:(CGFloat)spacing;
    /** Distributes the views in this array equally along the selected axis in their superview. Views will be the same size (fixed) in the dimension along the axis and will have spacing (variable) between them. */
    - (NSArray *)autoDistributeViewsAlongAxis:(ALAxis)axis
    alignedTo:(ALAttribute)alignment
    withFixedSize:(CGFloat)size;
    //...

    Ya que es de código abierto, si usted está interesado en ver cómo se logra esto sin espaciador vistas sólo echar un vistazo a la aplicación. (Depende aprovechando tanto la constant y multiplier para las restricciones.)

    • Buen trabajo! A pesar de que probablemente debería cambiar el nombre de la repo de modo que usted puede hacer que esté disponible a través de cocoapods.
  8. 17

    La correcta y más fácil es el uso de la Pila de puntos de vista.

    1. Agregar sus etiquetas/vistas a la Pila de Vista:

    Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

    1. Seleccione la Pila de Ver y establecer Distribución a ser Igual Espaciado:

    Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

    1. Agregar de distancia al vecino más cercano restricciones a la Pila de Ver y actualizar los marcos:

    Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

    1. Agregar Altura restricciones a todas las etiquetas:

    Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

    1. Disfrutar De La Vista Previa:

    Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

    • Este es >=iOS 9.0 sólo para comprobar su destino de implementación antes de iniciar la aplicación 🙂 Genial para ver este ha sido añadido en cuando!
    • 2018 ahora, el uso de la pila de vista
  9. 9

    Estoy teniendo un problema similar y descubierto este post. Sin embargo, ninguno de los que actualmente proporciona respuestas a resolver el problema en la manera que usted desea. Ellos no hacen el espaciado igual, pero en lugar de distribuir el centro de las etiquetas igualmente. Es importante entender que este no es el mismo. He construido un pequeño diagrama para ilustrar esto.

    Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

    Hay 3 puntos de vista, todos los 20pt de altura. Utilizando cualquiera de los métodos sugeridos distribuye uniformemente en los centros de los puntos de vista y dar la muestra de diseño. Observe que el eje y centro de los puntos de vista son igualmente espaciados. Sin embargo, el espaciado entre superview y de la vista superior es 15pt, mientras que el espaciado entre las subvistas es sólo 5pt. Para las vistas espaciados igualmente, estos deben ser 10pt, es decir, todas las flechas azules debe ser 10pt.

    Sin embargo, no he venido para arriba con una buena solución genérica, sin embargo. Actualmente mi mejor idea es insertar «espaciado de puntos de vista» entre las subvistas y ajuste de las alturas de la separación vistas a ser igual.

    • He utilizado la solución de oculto espaciador puntos de vista, que funciona bien.
  10. 8

    He podido resolver esta totalmente en IB:

    1. Hacer restricciones para alinear el centro Y de cada uno de sus subvistas el borde inferior de la superview.
    2. Establecer el multiplicador de cada una de estas restricciones a 1/2n, 3/2n, 5/2n, …, n-1/2n, donde n es el número de subvistas que se están distribuyendo.

    Así que si usted tiene tres etiquetas, establecer los multiplicadores para cada una de esas limitaciones para 0.1666667, 0.5, 0.833333.

    • De hecho tuve que hacer 1/n 3/n 5/n 7/n hasta (2n-1)/n
    • Hizo esto en el código—salvavidas! Pero @HamzahMalik la respuesta que trabajó para mí.
  11. 5

    He encontrado un perfecto y sencillo método. El diseño automático no permite cambiar el tamaño de los espacios por igual, pero sí que permite cambiar el tamaño de las vistas igualmente. Simplemente poner unos invisible puntos de vista entre sus campos y decirle diseño automático para mantener el mismo tamaño. Funciona perfectamente!

    Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

    Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

    Una cosa de notar, sin embargo; cuando he reducido el tamaño en el diseñador de interfaz, a veces se quedaba confundido y a la izquierda una etiqueta donde estaba, y tenía un conflicto si el tamaño se ha cambiado por una cantidad impar. De lo contrario, funcionó a la perfección.

    edit: he encontrado que el conflicto se convirtió en un problema. Porque de eso, tomé uno de los espaciado de restricciones, eliminado y reemplazado con dos limitaciones, una mayor que o igual y menor o igual. Ambos eran del mismo tamaño y tuvieron una menor prioridad que las otras restricciones. El resultado no era más conflicto.

  12. 4

    Edificio en Ben Dolman la respuesta, esto distribuye los puntos de vista de manera más uniforme (con relleno, etc):

    +(NSArray *)constraintsForEvenDistributionOfItems:(NSArray *)views
    relativeToCenterOfItem:(id)toView vertically:(BOOL)vertically
    {
    NSMutableArray *constraints = [NSMutableArray new];
    NSLayoutAttribute attr = vertically ? NSLayoutAttributeCenterY : NSLayoutAttributeCenterX;
    CGFloat min = 0.25;
    CGFloat max = 1.75;
    CGFloat d = (max-min) / ([views count] - 1);
    for (NSUInteger i = 0; i < [views count]; i++) {
    id view = views[i];
    CGFloat multiplier = i * d + min;
    NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:view
    attribute:attr
    relatedBy:NSLayoutRelationEqual
    toItem:toView
    attribute:attr
    multiplier:multiplier
    constant:0];
    [constraints addObject:constraint];
    }
    return constraints;
    }
  13. 3

    Con las etiquetas de esto funciona bien, al menos:

    @"H:|-15-[first(==second)]-[second(==third)]-[third(==first)]-15-|

    Si el primero tiene el mismo ancho que el segundo, y el segundo, el tercero, y la tercera a la primera, entonces van a tener la misma anchura… Se puede hacer tanto en el plano horizontal (H) y vertical (V).

  14. 3

    swift 3 versión

    let _redView = UIView()
    _redView.backgroundColor = UIColor.red
    _redView.translatesAutoresizingMaskIntoConstraints = false
    let _yellowView = UIView()
    _yellowView.backgroundColor = UIColor.yellow
    _yellowView.translatesAutoresizingMaskIntoConstraints = false
    let _blueView = UIView()
    _blueView.backgroundColor = UIColor.blue
    _blueView.translatesAutoresizingMaskIntoConstraints = false
    self.view.addSubview(_redView)
    self.view.addSubview(_yellowView)
    self.view.addSubview(_blueView)
    var views = ["_redView": _redView, "_yellowView": _yellowView, "_blueView":_blueView]
    var nslayoutConstraint_H = NSLayoutConstraint.constraints(withVisualFormat: "|->=0-[_redView(40)]->=0-[_yellowView(40)]->=0-[_blueView(40)]->=0-|", options: [.alignAllTop, .alignAllBottom], metrics: nil, views: views)
    self.view.addConstraints(nslayoutConstraint_H)
    var nslayoutConstraint_V = NSLayoutConstraint.constraints(withVisualFormat: "V:[_redView(60)]", options: NSLayoutFormatOptions.init(rawValue: 0), metrics: nil, views: views)
    self.view.addConstraints(nslayoutConstraint_V)
    let constraint_red = NSLayoutConstraint.init(item: self.view, attribute: .centerY, relatedBy: .equal, toItem: _redView, attribute: .centerY, multiplier: 1, constant: 0)
    self.view.addConstraint(constraint_red)
    let constraint_yellow = NSLayoutConstraint.init(item: self.view, attribute: .centerX, relatedBy: .equal, toItem: _yellowView, attribute: .centerX, multiplier: 1, constant: 0)
    self.view.addConstraint(constraint_yellow)
    let constraint_yellow1 = NSLayoutConstraint.init(item: _redView, attribute: .centerX, relatedBy: .equal, toItem: _yellowView, attribute: .leading, multiplier: 0.5, constant: 0)
    self.view.addConstraint(constraint_yellow1)
    let constraint_yellow2 = NSLayoutConstraint.init(item: _blueView, attribute: .centerX, relatedBy: .equal, toItem: _yellowView, attribute: .leading, multiplier: 1.5, constant: 40)
    self.view.addConstraint(constraint_yellow2)
    • Reflexiona sobre cómo este código responde a la preguntas de ayudar a los futuros visitantes.
  15. 2

    Sé que ha pasado un tiempo desde la primera respuesta, pero me encontré con el mismo problema y quiero compartir mi solución. Para las generaciones venideras…

    Me puse mis puntos de vista sobre viewDidLoad:

    - (void)viewDidLoad {
    [super viewDidLoad];
    cancelButton = [UIButton buttonWithType: UIButtonTypeRoundedRect];
    cancelButton.translatesAutoresizingMaskIntoConstraints = NO;
    [cancelButton setTitle:@"Cancel" forState:UIControlStateNormal];
    [self.view addSubview:cancelButton];
    middleButton = [UIButton buttonWithType: UIButtonTypeRoundedRect];
    middleButton.translatesAutoresizingMaskIntoConstraints = NO;
    [middleButton setTitle:@"Middle" forState:UIControlStateNormal];
    [self.view addSubview:middleButton];
    nextButton = [UIButton buttonWithType: UIButtonTypeRoundedRect];
    nextButton.translatesAutoresizingMaskIntoConstraints = NO;
    [nextButton setTitle:@"Next" forState:UIControlStateNormal];
    [self.view addSubview:nextButton];
    [self.view setNeedsUpdateConstraints];
    }

    Y, a continuación, en updateViewConstrains, primero voy a borrar todos los limita, entonces puedo crear las vistas de diccionario y, a continuación, calcular el espacio entre los puntos de vista. Después de eso, sólo tiene que utilizar el Lenguaje Visual de Formato para establecer las restricciones:

    - (void)updateViewConstraints {
    [super updateViewConstraints];
    [self.view removeConstraints:self.view.constraints];
    NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(cancelButton, nextButton, middleButton);
    float distance=(self.view.bounds.size.width-cancelButton.intrinsicContentSize.width-nextButton.intrinsicContentSize.width-middleButton.intrinsicContentSize.width-20-20)/  ([viewsDictionary count]-1);  //2 times 20 counts for the left & rigth margins
    NSNumber *distancies=[NSNumber numberWithFloat:distance];
    //   NSLog(@"Distancies: %@", distancies);
    //   
    //   NSLog(@"View Width: %f", self.view.bounds.size.width);
    //   NSLog(@"Cancel Width: %f", cancelButton.intrinsicContentSize.width);
    //   NSLog(@"Middle Width: %f", middleButton.intrinsicContentSize.width);
    //   NSLog(@"Next Width: %f", nextButton.intrinsicContentSize.width);
    NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|-[cancelButton]-dis-[middleButton]-dis-[nextButton]-|"
    options:NSLayoutFormatAlignAllBaseline
    metrics:@{@"dis":distancies}
    views:viewsDictionary];
    [self.view addConstraints:constraints];
    constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[nextButton]-|"
    options:0
    metrics:nil
    views:viewsDictionary];
    [self.view addConstraints:constraints];
    }

    La cosa buena acerca de este método es que usted tiene que hacer muy poco de matemáticas. No estoy diciendo que esta es la solución perfecta, pero me funciona para el diseño, yo estaba tratando de lograr.

    Espero te sirva de ayuda.

  16. 2

    Aquí es una solución que verticalmente el centro de cualquier número de subvistas, incluso si tienen tamaos. Lo que queremos hacer es un nivel medio de contenedor, en el centro que en el superview, a continuación, poner todas las subvistas en el contenedor y organizarlos con respecto a la otra. Pero, fundamentalmente, también es necesario limitar a la parte superior y parte inferior del recipiente, de manera que el envase puede ser del tamaño correcto y centrada en el superview. Por la figuración de la altura correcta de su subvistas, el contenedor puede ser centrada verticalmente.

    En este ejemplo, self es el superview en el que se están centrando todas las subvistas.

    NSArray *subviews = @[ (your subviews in top-to-bottom order) ];
    UIView *container = [[UIView alloc] initWithFrame:CGRectZero];
    container.translatesAutoresizingMaskIntoConstraints = NO;
    for (UIView *subview in subviews) {
    subview.translatesAutoresizingMaskIntoConstraints = NO;
    [container addSubview:subview];
    }
    [self addSubview:container];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:container attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual
    toItem:self attribute:NSLayoutAttributeLeft multiplier:1.0f constant:0.0f]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:container attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual
    toItem:self attribute:NSLayoutAttributeRight multiplier:1.0f constant:0.0f]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:container attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual
    toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.0f constant:0.0f]];
    if (0 < subviews.count) {
    UIView *firstSubview = subviews[0];
    [container addConstraint:[NSLayoutConstraint constraintWithItem:firstSubview attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual
    toItem:container attribute:NSLayoutAttributeTop multiplier:1.0f constant:0.0f]];
    UIView *lastSubview = subviews.lastObject;
    [container addConstraint:[NSLayoutConstraint constraintWithItem:lastSubview attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual
    toItem:container attribute:NSLayoutAttributeBottom multiplier:1.0f constant:0.0f]];
    UIView *subviewAbove = nil;
    for (UIView *subview in subviews) {
    [container addConstraint:[NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual
    toItem:container attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f]];
    if (subviewAbove) {
    [container addConstraint:[NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual
    toItem:subviewAbove attribute:NSLayoutAttributeBottom multiplier:1.0f constant:10.0f]];
    }
    subviewAbove = subview;
    }
    }
    • Esta es la mejor solución cuando se utilizan diferentes tamaños de puntos de vista que deben estar centrados.
  17. 2

    Me acaba de resolver mi problema con la característica del multiplicador. No estoy seguro de que funciona para todos los casos, pero a mí me ha funcionado perfectamente. Estoy en Xcode 6.3 FYI.

    Lo que terminé haciendo fue:

    1) en Primer lugar llegar a los botones de mi coloca en un 320 px de ancho de pantalla distribuido de la manera que quería que busque en 320 px dispositivo.

    Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

    2) Luego he añadido un Espacio restricción de superview en todos los botones de mi.

    Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

    3) Luego he modificado las propiedades del espacio, de modo que la constante fue de 0 y el multiplicador es el desplazamiento x dividido por el ancho de la pantalla (por ejemplo, mi primer botón de 8px desde el borde izquierdo así que me puse mi multiplicador para 8/320)

    4) a Continuación, el paso importante aquí es cambiar el segundo Elemento de la restricción relación a la superview.Tirados en lugar de superview.líder. Esto es clave porque superview.Líder es 0 y al final en mi caso es de 320, así que 8/320 es de 8 px en un 320 px dispositivo, a continuación, cuando el superview del ancho de cambios a 640 o lo que sea, los puntos de vista, todos se mueven en una proporción relativa a la anchura de los 320 px tamaño de la pantalla. La matemática es mucho más fácil de comprender.

    Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

  18. 2

    Muchas respuestas no son correctas, pero muchos de los condes. Aquí acabo de escribir una solución mediante programación, las tres vistas se alineación horizontal, sin el uso de espaciador vistas, pero sólo funciona cuando el ancho de las etiquetas se sabe cuando se utiliza en el guión gráfico.

    NSDictionary *views = NSDictionaryOfVariableBindings(_redView, _yellowView, _blueView);
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|->=0-[_redView(40)]->=0-[_yellowView(40)]->=0-[_blueView(40)]->=0-|" options:NSLayoutFormatAlignAllTop | NSLayoutFormatAlignAllBottom metrics:nil views:views]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_redView(60)]" options:0 metrics:nil views:views]];
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:_redView attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]];
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:_yellowView attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]];
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:_redView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:_yellowView attribute:NSLayoutAttributeLeading multiplier:0.5 constant:0]];
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:_blueView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:_yellowView attribute:NSLayoutAttributeLeading multiplier:1.5 constant:40]];
  19. 2

    Aquí hay otra respuesta. Yo estaba respondiendo a una pregunta similar, y vi el enlace que hace referencia a esta cuestión. Yo no ver ninguna respuesta similar a la mía. Así que, pensé en escribir aquí.

      class ViewController: UIViewController {
    override func viewDidLoad() {
    super.viewDidLoad()
    view.backgroundColor = UIColor.whiteColor()
    setupViews()
    }
    var constraints: [NSLayoutConstraint] = []
    func setupViews() {
    let container1 = createButtonContainer(withButtonTitle: "Button 1")
    let container2 = createButtonContainer(withButtonTitle: "Button 2")
    let container3 = createButtonContainer(withButtonTitle: "Button 3")
    let container4 = createButtonContainer(withButtonTitle: "Button 4")
    view.addSubview(container1)
    view.addSubview(container2)
    view.addSubview(container3)
    view.addSubview(container4)
    [
    //left right alignment
    container1.leftAnchor.constraintEqualToAnchor(view.leftAnchor, constant: 20),
    container1.rightAnchor.constraintEqualToAnchor(view.rightAnchor, constant: -20),
    container2.leftAnchor.constraintEqualToAnchor(container1.leftAnchor),
    container2.rightAnchor.constraintEqualToAnchor(container1.rightAnchor),
    container3.leftAnchor.constraintEqualToAnchor(container1.leftAnchor),
    container3.rightAnchor.constraintEqualToAnchor(container1.rightAnchor),
    container4.leftAnchor.constraintEqualToAnchor(container1.leftAnchor),
    container4.rightAnchor.constraintEqualToAnchor(container1.rightAnchor),
    //place containers one after another vertically
    container1.topAnchor.constraintEqualToAnchor(view.topAnchor),
    container2.topAnchor.constraintEqualToAnchor(container1.bottomAnchor),
    container3.topAnchor.constraintEqualToAnchor(container2.bottomAnchor),
    container4.topAnchor.constraintEqualToAnchor(container3.bottomAnchor),
    container4.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor),
    //container height constraints
    container2.heightAnchor.constraintEqualToAnchor(container1.heightAnchor),
    container3.heightAnchor.constraintEqualToAnchor(container1.heightAnchor),
    container4.heightAnchor.constraintEqualToAnchor(container1.heightAnchor)
    ]
    .forEach { $0.active = true }
    }
    func createButtonContainer(withButtonTitle title: String) -> UIView {
    let view = UIView(frame: .zero)
    view.translatesAutoresizingMaskIntoConstraints = false
    let button = UIButton(type: .System)
    button.translatesAutoresizingMaskIntoConstraints = false
    button.setTitle(title, forState: .Normal)
    view.addSubview(button)
    [button.centerYAnchor.constraintEqualToAnchor(view.centerYAnchor),
    button.leftAnchor.constraintEqualToAnchor(view.leftAnchor),
    button.rightAnchor.constraintEqualToAnchor(view.rightAnchor)].forEach { $0.active = true }
    return view
    }
    }

    Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

    Y de nuevo, esto se puede hacer muy fácilmente con la iOS9 UIStackViews así.

    class ViewController: UIViewController {
    override func viewDidLoad() {
    super.viewDidLoad()
    view.backgroundColor = UIColor.greenColor()
    setupViews()
    }
    var constraints: [NSLayoutConstraint] = []
    func setupViews() {
    let container1 = createButtonContainer(withButtonTitle: "Button 1")
    let container2 = createButtonContainer(withButtonTitle: "Button 2")
    let container3 = createButtonContainer(withButtonTitle: "Button 3")
    let container4 = createButtonContainer(withButtonTitle: "Button 4")
    let stackView = UIStackView(arrangedSubviews: [container1, container2, container3, container4])
    stackView.translatesAutoresizingMaskIntoConstraints = false
    stackView.axis = .Vertical
    stackView.distribution = .FillEqually
    view.addSubview(stackView)
    [stackView.topAnchor.constraintEqualToAnchor(view.topAnchor),
    stackView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor),
    stackView.leftAnchor.constraintEqualToAnchor(view.leftAnchor, constant: 20),
    stackView.rightAnchor.constraintEqualToAnchor(view.rightAnchor, constant: -20)].forEach { $0.active = true }
    }
    func createButtonContainer(withButtonTitle title: String) -> UIView {
    let button = UIButton(type: .Custom)
    button.translatesAutoresizingMaskIntoConstraints = false
    button.backgroundColor = UIColor.redColor()
    button.setTitleColor(UIColor.whiteColor(), forState: .Normal)
    button.setTitle(title, forState: .Normal)
    let buttonContainer = UIStackView(arrangedSubviews: [button])
    buttonContainer.distribution = .EqualCentering
    buttonContainer.alignment = .Center
    buttonContainer.translatesAutoresizingMaskIntoConstraints = false
    return buttonContainer
    }
    }

    Aviso de que es exactamente el mismo enfoque que el anterior. Añade cuatro contenedor de vistas que son llenados por igual y con una vista se agrega a cada pila de vista que se alinean en el centro. Pero, esta versión de UIStackView reduce algo de código y se ve bien.

  20. 1

    Otro enfoque podría ser la parte superior e inferior de las etiquetas tienen limitaciones relativas a la vista de la parte superior e inferior, respectivamente, y tienen la mitad de vista tienen la parte superior e inferior de las limitaciones con relación a la primera y tercera, respectivamente.

    Tenga en cuenta que usted tiene más control sobre las limitaciones de lo que podría parecer arrastrando vistas de cerca uno del otro hasta que los rectores de las líneas de puntos aparecen, estos indican las restricciones entre los dos objetos que se formó en lugar de entre el objeto y el superview.

    En este caso, entonces usted podría querer modificar las restricciones para ser «Mayor que o igual a» el valor deseado, en lugar de «igual» que les permita cambiar de tamaño. No estoy seguro si esto va a hacer exactamente lo que usted desea.

  21. 1

    Muy fácil para resolver este en InterfaceBuilder:

    Ajustar el centrado de la etiqueta (label2) a «Centro Horizontal en el Contenedor» y «Vertical con Centro en el Contenedor»

    Seleccione la centrada en la etiqueta y en la parte superior de la etiqueta (label1 + label2) y agregar DOS limitaciones de espacio Vertical. Uno con Mayor o Igual el mínimo espacio. Uno con Menor o Igual el máximo espaciamiento.

    La misma para el centrado de la etiqueta y la etiqueta de la parte inferior (label2 + label3).

    Además, usted también puede añadir las dos restricciones a label1 – la parte Superior del Espacio De SuperView y dos restricciones a label2 – Espacio Inferior A SuperView.

    El resultado será que todos los 4 espaciamientos va a cambiar sus tamaños igualmente.

    • He encontrado que esto sólo funciona cuando el tamaño de la superview, de modo que la separación se lleva exactamente el min o max valores. Cuando el tamaño de un valor en algún lugar entre el subvistas no se distribuyen de manera uniforme.
  22. 1

    He hecho una función que podría ser de ayuda.
    Este ejemplo de uso :

     [self.view addConstraints: [NSLayoutConstraint fluidConstraintWithItems:NSDictionaryOfVariableBindings(button1, button2, button3)
    asString:@[@"button1", @"button2", @"button3"]
    alignAxis:@"V"
    verticalMargin:100
    horizontalMargin:50
    innerMargin:25]];

    hará que distribución vertical (lo siento, no tenemos el 10 de reputación para incrustar imágenes). Y si cambia el eje y algunos margen de valores :

    alignAxis:@"H"
    verticalMargin:120
    horizontalMargin:20
    innerMargin:10

    Tendrás que distribución horizontal.

    Soy novato en iOS pero voilà !

    EvenDistribution.h

    @interface NSLayoutConstraint (EvenDistribution)
    /**
    * Returns constraints that will cause a set of subviews
    * to be evenly distributed along an axis.
    */
    + (NSArray *)  fluidConstraintWithItems:(NSDictionary *) views
    asString:(NSArray *) stringViews
    alignAxis:(NSString *) axis
    verticalMargin:(NSUInteger) vMargin
    horizontalMargin:(NSUInteger) hMargin
    innerMargin:(NSUInteger) inner;
    @end

    EvenDistribution.m

    #import "EvenDistribution.h"
    @implementation NSLayoutConstraint (EvenDistribution)
    + (NSArray *) fluidConstraintWithItems:(NSDictionary *) dictViews
    asString:(NSArray *) stringViews
    alignAxis:(NSString *) axis
    verticalMargin:(NSUInteger) vMargin
    horizontalMargin:(NSUInteger) hMargin
    innerMargin:(NSUInteger) iMargin
    {
    NSMutableArray *constraints = [NSMutableArray arrayWithCapacity: dictViews.count];
    NSMutableString *globalFormat = [NSMutableString stringWithFormat:@"%@:|-%d-",
    axis,
    [axis isEqualToString:@"V"] ? vMargin : hMargin
    ];
    for (NSUInteger i = 0; i < dictViews.count; i++) {
    if (i == 0)
    [globalFormat appendString:[NSString stringWithFormat: @"[%@]-%d-", stringViews[i], iMargin]];
    else if(i == dictViews.count - 1)
    [globalFormat appendString:[NSString stringWithFormat: @"[%@(==%@)]-", stringViews[i], stringViews[i-1]]];
    else
    [globalFormat appendString:[NSString stringWithFormat: @"[%@(==%@)]-%d-", stringViews[i], stringViews[i-1], iMargin]];
    NSString *localFormat = [NSString stringWithFormat: @"%@:|-%d-[%@]-%d-|",
    [axis isEqualToString:@"V"] ? @"H" : @"V",
    [axis isEqualToString:@"V"] ? hMargin : vMargin,
    stringViews[i],
    [axis isEqualToString:@"V"] ? hMargin : vMargin];
    [constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:localFormat
    options:0
    metrics:nil
    views:dictViews]];
    }
    [globalFormat appendString:[NSString stringWithFormat:@"%d-|",
    [axis isEqualToString:@"V"] ? vMargin : hMargin
    ]];
    [constraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:globalFormat
    options:0
    metrics:nil
    views:dictViews]];
    return constraints;
    }
    @end
  23. 1

    Sí, usted puede hacer esto únicamente en el interface builder y sin necesidad de escribir código – la única salvedad es que está cambiando el tamaño de la etiqueta en lugar de distribuir el espacio en blanco. En este caso, alinear la Etiqueta 2 X y y para el superview por lo que se fija en el centro. A continuación, establezca la etiqueta 1 del espacio vertical para el superview y de la etiqueta 2 de la norma, repita el procedimiento para la etiqueta 3. Después de la configuración de la etiqueta 2 de la forma más sencilla para establecer la etiqueta de la 1 y la 3 es para cambiar el tamaño de ellos hasta que encajen.

    Aquí es la horizontal de la pantalla, tenga en cuenta que el espacio vertical entre las etiquetas 1 y 2 se establece como estándar:Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

    Y aquí está el retrato de la versión:Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

    Me doy cuenta de que no son absolutamente 100% a igual distancia entre las líneas de base debido a la diferencia entre el estándar de espacio entre etiquetas y el estándar de espacio para el superview. Si eso le molesta, ajustar el tamaño a 0 en lugar de la estándar de

  24. 1

    Puedo establecer un valor de ancho para el primer elemento (>= un ancho) y una distancia mínima entre cada elemento (>= distancia). Entonces yo uso la tecla Ctrl al arrastrar el segundo, tercero… elemento en el primero para la cadena de dependencias entre los elementos.

    Uniformemente el espacio de múltiples puntos de vista dentro de un contenedor de vista

  25. 1

    Tarde a la fiesta, pero tengo una solución de trabajo para crear un menú horizontal con el espacio. Se puede hacer uso de == en NSLayoutConstraint

    const float MENU_HEIGHT = 40;
    - (UIView*) createMenuWithLabels: (NSArray *) labels
    //labels is NSArray of NSString
    UIView * backgroundView = [[UIView alloc]init];
    backgroundView.translatesAutoresizingMaskIntoConstraints = false;
    NSMutableDictionary * views = [[NSMutableDictionary alloc] init];
    NSMutableString * format = [[NSMutableString alloc] initWithString: @"H:|"];
    NSString * firstLabelKey;
    for(NSString * str in labels)
    {
    UILabel * label = [[UILabel alloc] init];
    label.translatesAutoresizingMaskIntoConstraints = false;
    label.text = str;
    label.textAlignment = NSTextAlignmentCenter;
    label.textColor = [UIColor whiteColor];
    [backgroundView addSubview: label];
    [label fixHeightToTopBounds: MENU_HEIGHT-2];
    [backgroundView addConstraints: [label fixHeightToTopBounds: MENU_HEIGHT]];
    NSString * key = [self camelCaseFromString: str];
    [views setObject: label forKey: key];
    if(firstLabelKey == nil)
    {
    [format appendString: [NSString stringWithFormat: @"[%@]", key]];
    firstLabelKey = key;
    }
    else
    {
    [format appendString: [NSString stringWithFormat: @"[%@(==%@)]", key, firstLabelKey]];
    }
    }
    [format appendString: @"|"];
    NSArray * constraints = [NSLayoutConstraint constraintsWithVisualFormat: (NSString *) format
    options: 0
    metrics: nil
    views: (NSDictionary *) views];
    [backgroundView addConstraints: constraints];
    return backgroundView;
    }
  26. 0

    Android tiene un método de encadenamiento de las vistas junto a su restricción basada en el diseño del sistema que quería imitar. Búsquedas me trajo aquí, pero ninguna de las respuestas bastante trabajado. Yo no quería usar StackViews porque tienden a me causa más dolor abajo de la línea que guardar hasta el frente. Terminé la creación de una solución que utiliza UILayoutGuides colocado entre los puntos de vista. El control de su anchura permite a los diferentes tipos de distribuciones, estilos de cadena en Android jerga. La función acepta un principio y el final de anclaje en lugar de un padre de la vista. Esto permite que la cadena se coloca entre dos arbitrario de puntos de vista en lugar de distribuir dentro de la vista principal. Se hace uso de UILayoutGuide que sólo está disponible en iOS 9+, pero eso no debería ser un problema.

    public enum LayoutConstraintChainStyle {
    case spread //Evenly distribute between the anchors
    case spreadInside //Pin the first & last views to the sides and then evenly distribute
    case packed //The views have a set space but are centered between the anchors.
    }
    public extension NSLayoutConstraint {
    static func chainHorizontally(views: [UIView],
    leadingAnchor: NSLayoutXAxisAnchor,
    trailingAnchor: NSLayoutXAxisAnchor,
    spacing: CGFloat = 0.0,
    style: LayoutConstraintChainStyle = .spread) -> [NSLayoutConstraint] {
    var constraints = [NSLayoutConstraint]()
    guard views.count > 1 else { return constraints }
    guard let first = views.first, let last = views.last, let superview = first.superview else { return constraints }
    //Setup the chain of views
    var distributionGuides = [UILayoutGuide]()
    var previous = first
    let firstGuide = UILayoutGuide()
    superview.addLayoutGuide(firstGuide)
    distributionGuides.append(firstGuide)
    firstGuide.identifier = "ChainDistribution\(distributionGuides.count)"
    constraints.append(firstGuide.leadingAnchor.constraint(equalTo: leadingAnchor))
    constraints.append(first.leadingAnchor.constraint(equalTo: firstGuide.trailingAnchor, constant: spacing))
    views.dropFirst().forEach { view in
    let g = UILayoutGuide()
    superview.addLayoutGuide(g)
    distributionGuides.append(g)
    g.identifier = "ChainDistribution\(distributionGuides.count)"
    constraints.append(contentsOf: [
    g.leadingAnchor.constraint(equalTo: previous.trailingAnchor),
    view.leadingAnchor.constraint(equalTo: g.trailingAnchor)
    ])
    previous = view
    }
    let lastGuide = UILayoutGuide()
    superview.addLayoutGuide(lastGuide)
    constraints.append(contentsOf: [lastGuide.leadingAnchor.constraint(equalTo: last.trailingAnchor),
    lastGuide.trailingAnchor.constraint(equalTo: trailingAnchor)])
    distributionGuides.append(lastGuide)
    //Space the according to the style.
    switch style {
    case .packed:
    if let first = distributionGuides.first, let last = distributionGuides.last {
    constraints.append(first.widthAnchor.constraint(greaterThanOrEqualToConstant: spacing))
    constraints.append(last.widthAnchor.constraint(greaterThanOrEqualToConstant: spacing))
    constraints.append(last.widthAnchor.constraint(equalTo: first.widthAnchor))
    constraints.append(contentsOf:
    distributionGuides.dropFirst().dropLast()
    .map { $0.widthAnchor.constraint(equalToConstant: spacing) }
    )
    }
    case .spread:
    if let first = distributionGuides.first {
    constraints.append(contentsOf:
    distributionGuides.dropFirst().map { $0.widthAnchor.constraint(equalTo: first.widthAnchor) })
    }
    case .spreadInside:
    if let first = distributionGuides.first, let last = distributionGuides.last {
    constraints.append(first.widthAnchor.constraint(equalToConstant: spacing))
    constraints.append(last.widthAnchor.constraint(equalToConstant: spacing))
    let innerGuides = distributionGuides.dropFirst().dropLast()
    if let key = innerGuides.first {
    constraints.append(contentsOf:
    innerGuides.dropFirst().map { $0.widthAnchor.constraint(equalTo: key.widthAnchor) }
    )
    }
    }
    }
    return constraints
    }
  27. -1

    ¿Por qué no acaba de crear un formato tableview y hacer isScrollEnabled = false

    • No entiendo la downvote, mi solución es pensar fuera de la caja. ¿Por qué pasar por el dolor de cabeza de la creación de una lista con el diseño automático cuando el cacao le da una lista en UITableView?

Dejar respuesta

Please enter your comment!
Please enter your name here