Actualizando UILabel Text Restablece el guión gráfico?

Me encontré con un escenario extraño, que simplemente no puedo resolver por mi count.

Empecé un pequeño escenario de testing, con una aplicación de vista única iOS casi vacía y un storyboard. Los tableros de historias contienen una label y UIView única, 10×10, solo para presentar el problema. Por supuesto, tienen los IBOutlets apropiados asignados y conectados:

@property (nonatomic, weak) IBOutlet UILabel *label; @property (nonatomic, weak) IBOutlet UIView *dot; 

En el método (void) viewDidLoad, comienzo un timer y lo agrego al ciclo de ejecución así:

 - (void)viewDidLoad { [super viewDidLoad]; NSTimer * timer = [NSTimer timerWithTimeInterval:0.5 target:self selector:@selector(doSomething) userInfo:nil repeats:YES]; [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; } 

En el método (vacío) doAlgo hago lo siguiente:

 -(void)doSomething { // Lets move the dot to the right a bit further _dot.center = CGPointMake(_dot.center.x+1, _dot.center.y); // About every ten steps, update the label with the current // X position, to better show the problem CGFloat moduloResult = (float)((int)_dot.center.x % (int)10.0); if(moduloResult <= 0) _label.text = [NSString stringWithFormat:@"%f", _dot.center.x+1]; } 

Básicamente, cambio el centro de la pequeña vista de puntos 10×10 cada vez por 1, y cada 10ª vez actualizo la label para mostrar la position X actual. Para el caso, ni siquiera importa con lo que actualizo el text de la label, es importante que cambie. Y solo cambio el text cada 10 veces para mostrar mejor el problema aquí.

Si ejecuto ese código, el punto se moverá exactamente como está previsto a la derecha, pero cuando actualice el text de la label, la vista de puntos se restablecerá y volverá a su position original. Así que actualizar mi text de label restablece mis otras vistas en el Storyboard, lo que me confunde totalmente.

¿Alguien puede reproducir eso o incluso explicarlo?

Gracias a todos, de antemano 🙂

Alex

Pude reproducir el comportamiento descrito, por eso está sucediendo:

  1. De forma pnetworkingeterminada, la position de los elementos está determinada por las restricciones de AutoLayout generadas automáticamente
  2. Al cambiar la position del dot , solo está actualizando su marco actual, no las restricciones subyacentes
  3. Cambiar el text de UILabel posiblemente modifique el tamaño del UILabel de UILabel , por lo que su recuadro necesita recalcularse. Aquí, el layout completo se vuelve a calcular en function de las restricciones, y también se restablece el marco del dot .

Para resolver, sugiero especificar correctamente las restricciones de AutoLayout y actualizarlas en lugar de la position directamente.

Eso fue más o less, las limitaciones de AutoLayout hicieron que la vista volviera siempre a su lugar original, lo cual tiene sentido supongo, eso es lo que se supone que haga AutoLayout.

Entonces, ya que quería que mi pequeña vista de puntos 10×10 se moviera por la pantalla (para propósitos prácticos, cambié mi código. Intento explicarlo, la falta de reputación solo me impide publicar las imágenes apropiadas.

Hice dos restricciones de AutoLayout personalizadas, diciéndole que mantenga la vista siempre 120px desde la izquierda de la supervisión y 100px desde la parte superior de la supervisión. También especificé la restricción para un ancho y una altura fijos de cada 10. Dado que para una restricción válida necesitas la combinación de x e y también de altura y ancho (al less en la medida en que yo lo entiendo).

  - | | Constraint *n* from top | |------| Constraint | view | *n* from left | _dot | |--------------- |------| 

Luego creé dos IBOutlets para las dos Restricciones:

 @property (weak, nonatomic) IBOutlet NSLayoutConstraint *c1X; @property (weak, nonatomic) IBOutlet NSLayoutConstraint *c1Y; 

Cambié mi método (vacío) doAlgo a esto:

 -(void)doSomething { // Lets move the dot to the right a bit // further by changing its Constraint _c1X.constant++; // About every ten steps, update the labe with the current // X position, to better show the problem CGFloat moduloResult = (float)((int)_dot.center.x % 10); if(moduloResult <= 0) _label.text = [NSString stringWithFormat:@"%f - %f - %f", _c1X.constant, _dot.center.x, _dot.center.y]; } 

Funciona, el cambio de la restricción en lugar de la vista real ahora mueve la vista sobre la pantalla. Si esta es la mejor práctica, no lo sé. Si no lo hubiera intentado con fines prácticos, siguiendo un tutorial antiguo, no lo haría en primer lugar.

Con la esperanza de que esto pueda ayudar un día. Cualquier comentario o mejora son bienvenidos 🙂

Alex