En una investigación más a fondo (ver la jerarquía de la subvista de la celda) Interface Builder coloca las subvistas dentro de la celda contentView
, simplemente no se ve así.
La causa principal del problema fue iOS 6 autolayout. Cuando la celda se coloca en modo de edición (y sangría), el contentView
también está sangrado, por lo que es lógico pensar que todas las subvistas dentro del contentView
se moverán (sangría) en virtud de estar dentro del contentView
. Sin embargo, todas las restricciones de autolayout aplicadas por Interface Builder parecen ser relativas al UITableViewCell
, en lugar del contentView
. Esto significa que, aunque las sangrías contentView
, las subvistas contenidas en las restricciones no se hacen cargo.
Por ejemplo, cuando coloqué un UILabel
en la celda (y lo coloqué a 10 puntos desde el lado izquierdo de la celda), IB aplicó automáticamente una restricción "Espacio horizontal (10)". Sin embargo, esta restricción es relativa al UITableViewCell
NO al contentView
. Esto significa que cuando se sangra la celda y se mueve el contentView
, la etiqueta se mantiene puesta ya que cumple con la restricción de permanecer 10 puntos desde el lado izquierdo del UITableViewCell
.
Lamentablemente (hasta donde yo sé) no hay forma de eliminar estas restricciones creadas por IB desde dentro de IB, así que así es como resolví el problema.
Dentro de la subclase UITableViewCell
para la celda, creé un IBOutlet
para esa restricción llamada cellLabelHSpaceConstraint
. También necesita un IBOutlet
para la etiqueta en sí, que llamé al cellLabel
. entonces he implementado el método de -awakeFromNib
según abajo:
- (void)awakeFromNib {
// -------------------------------------------------------------------
// We need to create our own constraint which is effective against the
// contentView, so the UI elements indent when the cell is put into
// editing mode
// -------------------------------------------------------------------
// Remove the IB added horizontal constraint, as that's effective
// against the cell not the contentView
[self removeConstraint:self.cellLabelHSpaceConstraint];
// Create a dictionary to represent the view being positioned
NSDictionary *labelViewDictionary = NSDictionaryOfVariableBindings(_cellLabel);
// Create the new constraint
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|-10-[_cellLabel]" options:0 metrics:nil views:labelViewDictionary];
// Add the constraint against the contentView
[self.contentView addConstraints:constraints];
}
En resumen, lo anterior se eliminará la restricción de espaciado horizontal que añade automáticamente IB (como es eficaz contra la UITableViewCell
en lugar de la contentView
) y que a continuación, definir y añadir nuestra propia restricción al contentView
.
En mi caso, todos los otros UILabels
en la celda se colocaron según la posición del cellLabel
, así que cuando arreglé la restricción/posicionamiento de este elemento, todos los demás lo siguieron y colocaron correctamente. Sin embargo, si tiene un diseño más complejo, puede que necesite hacer esto para otras subvistas también.
¿Estás seguro de eso? La última vez que distribuí una celda en una plumilla, aunque parecía que no estaba agregando vistas secundarias a la vista de contenido, en el tiempo de ejecución en el depurador todo estaba en la vista de contenido. Vale la pena verificar en el depurador si aún no lo has hecho ... –
Gracias Carl. Tenías razón: todas las subvistas se agregaron a contentView. El problema estaba relacionado con el autolayout de iOS 6. He incluido una respuesta que describe cómo se solucionó el problema. – Skoota