top pantalla interfaces human guidelines color cambio cambiar bar apple ios uitableview autolayout margin

ios - interfaces - mi iphone cambio de color la pantalla



UITableViewCell con margen izquierdo de distribución automática diferente en iPhone y iPad (5)

Estoy usando un UITableView agrupado con celdas estáticas para una pantalla / escena de opciones. Todo se hace en Xcode 6.1 / iOS 8.1.x / Storyboard usando Autolayout. Dentro de los grupos de tablas hay tipos mixtos de celdas y hay dos tipos que me causan problemas:

  1. Celdas con estilo personalizado y
  2. Celdas con estilo "Detalle correcto"

En la celda # 1 puedo establecer una restricción para el margen izquierdo entre la etiqueta y el contenedor principal. En la celda # 2 no puedo establecer ninguna restricción en Interface Builder hasta donde yo sé. He establecido el margen izquierdo en la etiqueta en la celda # 1 para que se alinee con la etiqueta en la celda # 2. Todo se ve bien en un iPhone, pero si muestro la misma tabla en un iPad donde el tamaño del contenedor de la vista de tabla es la mitad del tamaño de la pantalla, la celda # 2 obtiene más margen (¿dinámicamente?) Mientras que la celda # 1 mantiene el margen absoluto I establecido en las restricciones. También intenté cambiar el margen izquierdo en la celda # 1 con el atributo "relativo al margen" pero fue en vano.

iPhone:

iPad (con ancho de vista de tabla = 1/2 tamaño de pantalla)

Entonces la pregunta es: ¿Cómo configuro las restricciones para la etiqueta en la celda # 1 para que se alinee como la celda # 2?

Aquí también hay un enlace a un proyecto de muestra de Xcode 6.1 que demuestra el problema. Ejecute en iPhone y iPad para ver la diferencia:

https://dl.dropboxusercontent.com/u/5252156/Code/tableViewTest.zip

Esta pregunta puede estar relacionada con la celda de tabla estática de diseño para iPhone y iPad , pero también puede diferir para iOS 8, ya que se supone que todo se adapta ahora. Es por eso que decidí publicar esta pregunta de todos modos.


Como arreglarlo

Después de luchar con el equipo de informes de errores de Apple con muchos proyectos de muestra y capturas de pantalla y diseccionar esa respuesta , descubrí que la solución para que sus celdas de estilo personalizado se comporten de manera consistente con respecto a sus márgenes y sea como los UITableViewCells predeterminados, debe hacerlo lo siguiente (principalmente basado en la respuesta de Becky , he resaltado lo que es diferente y lo que hizo que funcione para mí):

  1. Seleccione la vista de contenido de su celda en IB
  2. Ir al inspector de tallas
  3. En la sección Márgenes de diseño, marque Conservar márgenes de supervisión (no haga clic en el signo más)

  4. (Y aquí está la clave) Haga lo mismo para la celda en sí (el padre de la vista de contenido, si lo desea)

  5. Configure sus restricciones de la siguiente manera: Label.Leading = Superview.Leading Margin (con una constante de 0)

¡Ahora todas sus celdas tendrán su etiqueta consistente con las celdas predeterminadas! Esto funciona para mí en Xcode 7 y versiones posteriores e incluye la solución mencionada en el hilo al que me referí. IB y el simulador ahora deberían mostrar etiquetas correctamente alineadas.

También podría hacer algo de esto mediante programación, por ejemplo en la clase del controlador de vista:

cell.preservesSuperviewLayoutMargins = true cell.contentView.preservesSuperviewLayoutMargins = true

O podría configurarlo llamando a UIAppearance una vez al inicio (solo sé Swift, lo siento):

UITableViewCell.appearance().preservesSuperviewLayoutMargins = true UITableViewCell.appearance().contentView.preservesSuperviewLayoutMargins = true

Como y porque funciona

Como Ethan señaló amablemente, la propia documentación de Apple en UIView describe preservesSuperviewLayoutMargins siguiente manera:

Cuando el valor de esta propiedad es true , los márgenes de la supervista también se tienen en cuenta al diseñar el contenido. Este margen afecta a los diseños donde la distancia entre el borde de una vista y su supervista es menor que el margen correspondiente. Por ejemplo, es posible que tenga una vista de contenido cuyo marco coincida con precisión con los límites de su supervista. Cuando cualquiera de los márgenes de la supervista está dentro del área representada por la vista de contenido y sus propios márgenes, UIKit ajusta el diseño de la vista de contenido para respetar los márgenes de la supervista. La cantidad del ajuste es la cantidad más pequeña necesaria para garantizar que el contenido también esté dentro de los márgenes de la supervista.

Por lo tanto, si desea que el contenido de su celda se alinee con los márgenes de TableView (es bisabuelo si lo desea), debe tener los dos ascendentes de su contenido, la Vista de contenido y la Celda de tabla en sí, preservar los márgenes de su propia supervista.

Por qué esto no es un comportamiento predeterminado me sorprende: siento que la mayoría de los desarrolladores que no quieren personalizar todo esperarían esta "herencia" por defecto.


Después de leer las respuestas existentes y no encontrar una solución programática obvia, investigué un poco más y ahora tengo una buena respuesta para cualquiera que se enfrente a este problema.

En primer lugar, no es necesario establecer preservesSuperviewLayoutMargins en la vista de la celda o en la vista de contenido, como implican other answers . Si bien el valor predeterminado es false , cambiarlo a true no tuvo un efecto notable que pude ver.

La clave para que esto realmente funcione es la propiedad UIView en UIView . Con este valor, podemos anclar fácilmente el leadingAnchor de cualquier subvista al leadingAnchor de la guía. Así es como se ve en el código (y muy bien puede ser lo que IB está haciendo detrás de escena como en other ).

En una subclase de UITableViewCell , haría algo como esto:

override func updateConstraints() { let margins = contentView.layoutMarginsGuide let leading = margins.leadingAnchor subview1.leadingAnchor.constraintEqualToAnchor(leading).active = true subview2.leadingAnchor.constraintEqualToAnchor(leading).active = true super.updateConstraints() }

Actualización de Swift 4.1

override func updateConstraints() { let margins = contentView.layoutMarginsGuide let leading = margins.leadingAnchor subview1.leadingAnchor.constraint(equalTo: leading).isActive = true subview2.leadingAnchor.constraint(equalTo: leading).isActive = true super.updateConstraints() }

¡Eso es todo! Si está desarrollando versiones de iOS anteriores a iOS 9, deberá sustituir los anclajes de diseño y utilizar en su lugar el recuadro layoutMargins .

Nota: Escribí una biblioteca para hacer que el anclaje sea un poco más bonito, si prefieres una sintaxis más limpia. Se llama SuperLayout y está disponible en Cocoapods. En la parte superior de su archivo fuente, importe SuperLayout :

import SuperLayout

Y luego, en su bloque de diseño, use ~~ , ≤≤ y ≥≥ para fijar restricciones:

override func updateConstraints() { let margins = contentView.layoutMarginsGuide subview1.leadingAnchor ~~ margins.leadingAnchor subview2.leadingAnchor ~~ margins.leadingAnchor super.updateConstraints() }

ios 11+: deje márgenes = contentView.directionalLayoutMargins ... en caso de que necesite adaptarse a LTR y RTL fuera de la caja. Supongo que la mayoría de la gente necesita eso.


Me encontré con el mismo problema que tú y encontré una solución.

Primero, un poco de historia: desde iOS 8, las celdas de vista de tabla predeterminadas respetan los layoutMargins de layoutMargins la layoutMargins para adaptarse a diferentes rasgos (también conocidos como pantallas o dispositivos). Por ejemplo, los márgenes de diseño en todos los iPhones (excepto iPhone 6 Plus cuando se muestran en una hoja de formulario) son {8, 16, 8, 16} . En iPad son {8, 20, 8, 20} . Entonces, ahora sabemos que hay una diferencia de 4 píxeles, que probablemente su celda personalizada de vista de tabla no respeta.

La subclase de celdas de la vista de tabla debe adaptar la restricción del margen izquierdo cuando cambian los márgenes de diseño.

Aquí está el fragmento de código relevante:

- (void)layoutMarginsDidChange { [super layoutMarginsDidChange]; self.leftLayoutMarginConstraint.constant = self.layoutMargins.left; self.rightLayoutMarginConstraint.constant = self.layoutMargins.right; }

Adaptarse a los márgenes de diseño en el código le permite obtener siempre el relleno adecuado para su etiqueta de título.

También puede echar un vistazo a una de mis subclases UITableViewCell que ya respetan los márgenes de diseño: https://github.com/bhr/BHRExtensions/blob/master/BHRExtensions/Utilities/BHRTitleAndValueTableCell.m

Salud


Pude obtener celdas con estilos personalizados alineados con las celdas estándar haciendo lo siguiente:

  1. En el esquema del documento, seleccione la "Vista de contenido" para la celda con el estilo personalizado.
  2. Ir al inspector de tamaño.
  3. En el menú desplegable "Márgenes de diseño", presione el pequeño símbolo más junto a "Conservar márgenes de supervisión".
  4. Seleccione la clase de tamaño de iPad, que es "Ancho normal x Altura normal".
  5. Marque la casilla de verificación al lado de "Preserve Superview Margins".
  6. Resuelva las advertencias de diseño automático actualizando los marcos.

Esto funcionó para mí en Xcode 7; Espero que también funcione en Xcode 6.


Tuve este problema al probar en un iPad Air, OS 10.1.1. Los encabezados de las tablas estaban sangrados mucho más de lo que deberían, y era aún peor en orientación horizontal. Pero estaban bien en iphones hasta OS 11.

La solución sorprendente fue la siguiente línea de código, justo después de que se creó la tabla (lo siento, solo trabajo en C #, pero es fácil resolver los equivalentes de Obj-C y Swift):

myTableView.SeparatorInset = myTableView.SeparatorInset;

¡Entonces todo quedó sangrado como debería ser!