iphone objective-c ios ipad

iphone - Cambiar la posición de UIButton personalizado en UITableViewCell personalizado



objective-c ios (7)

Necesito cambiar la posición de UIButton dinámicamente. Lo hago en cellForRowAtIndexPath: Altere el marco del botón en ese método. El cambio no se muestra cuando la tabla se muestra inicialmente. Pero cuando me desplazo más allá de las celdas y vuelvo, se muestra. Del mismo modo, cuando me desplazo por primera vez a las celdas no visibles inicialmente, no hay cambios. El cambio ocurre cuando me desplazo a él por segunda vez.

He intentado setNeedsDisplay: tanto en el botón personalizado como en la vista de tabla. He hecho esto incluso en willDisplayCell:forRowAtIndexPath: ¿Cómo puedo solucionar esto?

EDITAR: Olvidé mencionar que estoy cargando la UITableViewCell desde un archivo de punta. Aquí está el código para cambiar el tamaño del marco.

label1.text = //text from some source label1.text = [label1.text stringByAppendingString:@" |"]; [label1 sizeToFit]; CGRect frameAfterResize=label1.frame; float x=frameAfterResize.origin.x+frameAfterResize.size.width; button.frame=CGRectMake(x+2, button.frame.origin.y, button.frame.size.width,button.frame.size.height);


  1. Cree su propia subclase UITableViewCell
  2. Conecte todos los enchufes (botón también) de su xib a esta clase
  3. Cree un método personalizado en esta subclase UITableViewCell, por ejemplo, vea a continuación, no puede formatearlo allí.
  4. en cellForRowAtIndexPath: use este método para cambiar el cuadro y redibujar la celda

    [cell setNewFrame: ....];

Funciona bien para mí

-(void)setNewFrame:(CGRect)newFrame { myButton.frame=newFrame; [self setNeedsDisplay]; }

si quiere ajustar el botón al texto

-(void)setNewCaption:(NSString)newCaption { label1.text = newCaption label1.text = [label1.text stringByAppendingString:@" |"]; // calculate new frame myButton.frame=//new frame [self setNeedsDiplay]; }


¿Has intentado volver a cargar la tabla después de cambiar el marco de la celda mediante el uso de

[self.tableView reloadData]

Creo que debería resolver tu problema.


Al dibujar UITableViews, las celdas de tabla se vuelven a utilizar, por lo que solo hay una instancia de una UITableViewCell identificada por la cadena que se pasa a dequeueReusableCellWithIdentifier :.

Si actualiza la celda en el método cellForRowAtIndexPath: no tendrá el efecto esperado, cada vez se referirá a la misma celda (por lo que cada celda tendrá el botón en la misma posición). De ahí el problema que está viendo que el desplazamiento hace que el botón cambie de posición.

Lo más fácil para solucionar su problema es modificar el código para detener la reutilización de celdas creando una nueva celda cada vez en cellForRowAtIndexPath. Actualiza el código de esta manera:

// comment out this line // cell = [tableView dequeueReusableCellWithIdentifier:identifier]; NSArray *nib = [[NSBundle mainBundle] loadNibNamed:nibName]; cell = [nib objectAtIndex:0];

Sin embargo, tenga en cuenta que se prefieren las celdas de reutilización por razones de eficiencia (para ahorrar memoria y reducir las asignaciones de memoria).

Su solución ideal es crear una subclase personalizada de UITableViewCell y actualizar la posición de UIButton en el método layoutSubviews.


Cree su propia subclase UITableViewCell. Cree y agregue el botón al contenido de la celda en su método init, o cree y añádalo perezosamente a través de una propiedad de acceso. Anular diseño. Publique y coloque el botón como desee.

Algo como esto:

@implementation MyCustomCell - (void) init { self = [super initWithStyle: UITableViewCellStyleDefault reuseIdentifier: nil]; if ( self != nil ) { _myButton = [[UIButton buttonWithType: UIButtonTypeRoundedRect] retain]; [self.contentView addSubview: _myButton]; } return self; } - (void) layoutSubviews { [super layoutSubviews]; // dynamic layout logic: if ( ... ) { _myButton.frame = CGRectMake( 10, 10, 100, 30 ); } else { _myButton.frame = CGRectMake( 20, 10, 50, 30 ); } }

Alternativamente, puede intentar hacer el diseño de la celda en - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath


Llame setNeedsDisplay con su objeto UITableViewCell .

[cell setNeedsDisplay];

en cellForRowAtIndexPath:


Si no se muestra como se requiere inicialmente, pero después del desplazamiento, entonces supongo que está alterando la posición de la etiqueta solo cuando una celda se quita de la cola y no cuando se carga originalmente desde el plumín.

No has dado esta parte de tu método cellForRowAtIndexPath, así que no puedo dar ningún consejo más específico en este momento, pero el código anterior no se está ejecutando o label1 es nulo cuando se label1 una nueva celda (es decir, cuando devuelve el método de dequeue) nada y se carga desde la punta).


Tuve el mismo problema en el que estaba cargando la celda desde una punta, pero ninguna de las soluciones anteriores funcionó por completo para mí. Resolvieron el problema en pocos escenarios, pero no en todos.

Aquí está la solución que funcionó para todos los escenarios.

@implementation MyChannelCell -(void)drawRect:(CGRect)rect { [super drawRect:rect]; //Calling from here fixed issue for first time cell load [self alignCellViews]; } -(void)layoutSubviews { [super layoutSubviews]; //Calling from here fixed issue for coming back to the tableview from other ViewConroller [self alignCellViews]; } /** Method to change the layout and positions of sub-views */ -(void)alignCellViews { //Code to position sub-views //self.lblSubscribers is an outlet from nib of type UILabel [self.lblSubscribers setFrame:CGRectMake(140, 26, 36, 26)]; [self setNeedsDisplay]; } @end