2010-03-19 22 views
7

Tengo una UITableViewCell personalizada que contiene varios UIButtons. La posición del marco de cada botón es relativa al ancho de la celda. Establezco autoresizingMask = UIViewAutoresizingFlexibleWidth para que ajuste el ancho de la celda y el botón se posiciona correctamente cuando la aplicación comienza con el dispositivo en modo horizontal o vertical.Girar una UITableViewCell personalizada

El problema es cuando el dispositivo se gira de un modo a otro, los botones no ajustan las posiciones porque el UITableViewCell es reutilizable. En otras palabras, la celda no se inicializa en función del nuevo ancho de UITalbeView porque se llama a la función de la celda initWithStyle antes de que se gire el dispositivo y no se vuelve a llamar después de la rotación del dispositivo. ¿Alguna sugerencia?

+0

Termina la solución es mucho más simple. Solo necesita establecer self.contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth; self.contentView.autoresizesSubviews = YES; NO funciona al establecer self.autoresizingMask. –

+0

Tengo el mismo problema que usted y estaba pensando en usar etiquetas de celda específicas para cada caso de orientación, ya que esta idea surgió después de pensarlo un momento. Usando self.contentView.autoresizesSubviews = YES no funciona de mi lado. – user255607

+0

Finalmente usé otro truco. – user255607

Respuesta

7

Después de pasar horas de investigación (incluidas las publicaciones en este sitio), no pude encontrar ninguna solución. Pero una bombilla se enciende de repente. La solución es muy simple. Solo detecte si la orientación del dispositivo es horizontal o vertical y defina ReusableCellIdentifier con un nombre diferente para cada uno.

static NSString*Identifier; 

if ([UIDevice currentDevice].orientation!=UIDeviceOrientationLandscapeLeft && [UIDevice currentDevice].orientation!=UIDeviceOrientationLandscapeRight) { 
       Identifier= @"aCell_portrait"; 
      } 
      else Identifier= @"DocumentOptionIdentifier_Landscape"; 


    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier]; 
+1

No funciona para celdas personalizadas ... –

6

La respuesta anterior tiene un problema grave. Debe usar [UIApplication sharedApplication] .statusBarOrientation en lugar de [UIDevice currebtDevice] .orientation porque la orientación del dispositivo no tiene nada que ver con la orientación de la interfaz. La orientación del dispositivo es la rotación física basada en el acelerómetro.

+0

Gracias por informarnos sobre la segunda opción. De hecho, ambos pueden funcionar. Consulte http://stackoverflow.com/questions/2738734/get-current-orientation-of-ipad –

+2

Lo siento, no tiene razón.La orientación del dispositivo tiene 6 opciones diferentes, mientras que la orientación de la interfaz tiene 4. Si su dispositivo está sobre la mesa, la orientación del dispositivo informará "Cara arriba", que no tiene nada en común con la orientación actual de la interfaz. – Hrissan

+0

Hrissan, gracias por la corrección. –

1

Deberá corregir el ancho de su celda (suponiendo que la altura sea la misma en modo retrato y paisaje) dentro de su método cellForRowAtIndexPath. Eso es lo que está funcionando aquí. Solía ​​crear una TableViewCell personalizada con IB y siempre se inicializa para un retrato de ancho de 320 px. Al definir el marco funciona como se esperaba, incluso si la celda se "reutiliza" de la cola.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
... 
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 
if (cell == nil) { 
    // create cell here... 
} 

// Adjust cell frame width to be equal to tableview frame width 
cell.frame = CGRectMake(0, 0, tableView.frame.size.width, cell.frame.size.height); 
... 
} 
13

Desde UITableViewCell es también un UIView, se puede reemplazar el método setFrame. Cada vez que gira la vista de tabla, se llamará a este método para todas las celdas.

-(void)setFrame:(CGRect)frame 
{ 
    [super setFrame:frame]; 

    //Do your rotation stuffs here :) 
} 
0

Tuve un problema similar y esta publicación me ayudó. En mi caso tengo una clase personalizada declarada en un archivo separado, y en este archivo que tiene el siguiente código en layoutSubviews:

//PORTRAIT CELL 
if ([UIDevice currentDevice].orientation!=UIDeviceOrientationLandscapeLeft && 
    [UIDevice currentDevice].orientation!=UIDeviceOrientationLandscapeRight) 
{ 
    //build the custom content views for portrait mode here 
} 
else 
{ 
    //build the custom content views for landscape mode here 
} 

Luego, en mi controlador de vista que acabo de implementar willAnimateRotationToInterfaceOrientation: y enviar el mensaje de reloadData a mi mesa ver.

Con esto no tengo que tocar el método cellForRow.

+1

usando el layoutSubviews no necesitas usar el reloadData, y es mejor si no lo usas, porque si estás en el modo de edición con el botón de borrar que se muestra, y rotar, el botón eliminar desaparecerá debido a reloadData – jcesarmobile

2

La respuesta marcada funciona como un encanto en las versiones anteriores de iOS. Para iOS 6.0 utilicé el siguiente código:

static NSString *Identifier; 
if (self.interfaceOrientation==UIInterfaceOrientationPortrait) { 
    [email protected]"aCell_portrait"; 
} 
else { 
    [email protected]"DocumentOptionIdentifier_Landscape"; 
} 

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier]; 
Cuestiones relacionadas