2011-01-16 13 views
31

El UITableView agrupado coloca un margen entre el borde de la vista y las celdas de la tabla. De manera molesta (para mí), este margen es una función del ancho de la vista.Cómo determinar el margen de una UITableView agrupada (o mejor, cómo configurarla)?

En mi aplicación tengo dos UITableViews de diferentes anchuras que estoy buscando para alinear los bordes de la celda.

¿Es posible obtener este margen? ¿O mejor es posible establecer este margen?

aplausos, --Ben

+0

Es la solución No esbozado trabajando para usted? –

Respuesta

18

Al crear (y usando!) Una subclase de UITableViewCell, que posiblemente pueden lograr lo que estás buscando. Simplemente mueva la vista de contenido y la vista de fondo en las vistas de layouts, como en el ejemplo de código siguiente que desplaza las partes visibles de la celda 20pt hacia la derecha.

- (void) layoutSubviews 
{ 
    NSLog (@"Cell/contentview/backgroundview before:\n%@\n%@\n%@", self, self.contentView, self.backgroundView); 
    [super layoutSubviews]; 
    CGRect frame = self.backgroundView.frame; 
    frame.origin.x += 20; 
    frame.size.width -= 20; 
    self.backgroundView.frame = frame; 
    frame = self.contentView.frame; 
    frame.origin.x += 20; 
    frame.size.width -= 20; 
    self.contentView.frame = frame; 

    NSLog (@"Cell/contentview/backgroundview after:\n%@\n%@\n%@", self, self.contentView, self.backgroundView); 
} 
+2

-1 La respuesta de Matthew Thomas usa los márgenes incorporados. – bentford

+3

De acuerdo, sin embargo, esa solución parece frágil, ¡como depende de los detalles internos! –

53

Agrupados TableView Anchura en relación con margen de celda

TBWidth (0 a 20) Margen izquierdo = TBWidth - 10

TBWidth (20 a 400) Margen izquierdo = 10

TB Ancho (401 a 546) Margen izquierdo = 31

TB Ancho (547 a 716) Left Margin = APX 6% de tableView

TBWidth (717 a 1024) Margen izquierdo = 45

- (float) groupedCellMarginWithTableWidth:(float)tableViewWidth 
{ 
    float marginWidth; 
    if(tableViewWidth > 20) 
    { 
     if(tableViewWidth < 400) 
     { 
      marginWidth = 10; 
     } 
     else 
     { 
      marginWidth = MAX(31, MIN(45, tableViewWidth*0.06)); 
     } 
    } 
    else 
    { 
     marginWidth = tableViewWidth - 10; 
    } 
    return marginWidth; 
} 
+1

Confirmado que esto funciona. ¿Cómo te enteraste de ésto? ¡¡Eres fabuloso!! – bentford

+0

Sí, definitivamente funcionó ... pero es triste que esta es la mejor manera que he encontrado para hacerlo jaja. – tomwilson

+2

Esto parece magia negra ... de todos modos +1: P – daveoncode

0

Sólo en caso de que cualquier persona necesita esto, la función para el título de la sección margen izquierdo cuando se obtienen de tableView:titleForHeaderInSection: parece ser:

- (float)marginForSectionTitleOnGroupedTableView { 
    float width = self.width; 

    if (width <= 400) return 19; 
    else if (width >= 401 && width < 547) return 40; 
    else if (width >= 547 && width < 560) return 41; 
    else if (width >= 560 && width < 573) return 42; 
    else if (width >= 573 && width < 586) return 43; 
    else if (width >= 586 && width < 599) return 44; 
    else if (width >= 599 && width < 612) return 45; 
    else if (width >= 612 && width < 625) return 46; 
    else if (width >= 625 && width < 639) return 47; 
    else if (width >= 639 && width < 652) return 48; 
    else if (width >= 652 && width < 665) return 49; 
    else if (width >= 665 && width < 678) return 50; 
    else if (width >= 678 && width < 691) return 51; 
    else if (width >= 691 && width < 704) return 52; 
    else if (width >= 704 && width < 717) return 53; 

    // if (width >= 717) 
    return 54; 
} 

Para anchos superiores a 401, el margen parece ser de alrededor del 7,5% del ancho de la vista de tabla; pero cuando intentaba alinear alguna otra vista con el título de la sección, la alineación no funcionaba como se esperaba; entonces el enfoque detallado parece funcionar mejor.

+0

Utilicé esto que funciona lo suficientemente bien para iPad pero para iPhone los márgenes cuando el paisaje (y por lo tanto más de 401px) todavía son 19px. Sin embargo, solo agregar la verificación adicional del dispositivo funciona muy bien. –

12

Estaba usando la implementación de Matthew Thomas pero no es confiable (está rota si usa autorrotación en los controladores) y tiene un montón de código codificado ... Me di cuenta de que hay una solución muy simple, mi implementación es una sola línea de código:

- (float)cellMargins 
{ 
    return self.backgroundView.frame.origin.x * 2; 
} 

esto es mucho mejor OMI :)

EDIT: mi aplicación no era fiable también (que no funciona correctamente cuando se cambia a/desde el modo de edición), esta es mi implementación final (I manejó los márgenes derecho e izquierdo por separado):

- (float)leftMargin 
{ 
    return self.contentView.frame.origin.x; 
} 

- (float)rightMargin 
{ 
    CGRect frame = self.contentView.frame; 
    float containerWidth = frame.size.width; 
    float margin = self.frame.size.width - (containerWidth + frame.origin.x); 
    return margin; 
} 

- (float)cellMargins 
{ 
    return ([self leftMargin] + [self rightMargin]); 
} 
+0

este es el trabajo excelente, excelente trabajo – Marcin

+5

Su solución se ve muy bien, pero no se puede utilizar en los casos en que necesita conocer los márgenes antes de que se crean las células – flagg19

1

Me gustaría complementar la respuesta de Matthew con un código para configurar el margen fijo.

  1. Subclase UITableViewCell.
  2. Implementar setFrame:
 
- (void)setFrame:(CGRect)frame 
{ 
    CGFloat inset = 15.0; 
    CGFloat tableWidth = 400.0; 
    frame.origin.x -= [self groupedCellMarginWithTableWidth:tableWidth] - inset; 
    frame.size.width = frame.size.width + 2 * ([self groupedCellMarginWithTableWidth:tableWidth] - inset); 
    [super setFrame:frame]; 
} 

Esto establecerá margen izquierda y derecha para 15,0 mientras anchura de la tabla puede variar.

6

Se actualizó el código de Matthew Thomas para el cálculo de los márgenes de celda. Creado a través de la categoría UITableView. Esto puede ser útil cuando necesita determinar la altura del texto en la celda y no conoce el ancho de esa celda.

Así, célula real se puede calcular como

cell.width = tableView.width - tableView.cellsMargin * 2; 

Una aquí está el código

@implementation UITableView (CellsMargins) 

// This is black magic 
// from 
// http://stackoverflow.com/questions/4708085/how-to-determine-margin-of-a-grouped-uitableview-or-better-how-to-set-it 

- (CGFloat)cellsMargin { 

    // No margins for plain table views 
    if (self.style == UITableViewStylePlain) { 
     return 0; 
    } 

    // iPhone always have 10 pixels margin 
    if (! isIPad()) { 
     return 10; 
    } 

    CGFloat tableWidth = self.frame.size.width; 

    // Really small table 
    if (tableWidth <= 20) { 
     return tableWidth - 10; 
    } 

    // Average table size 
    if (tableWidth < 400) { 
     return 10; 
    } 

    // Big tables have complex margin's logic 
    // Around 6% of table width, 
    // 31 <= tableWidth * 0.06 <= 45 

    CGFloat marginWidth = tableWidth * 0.06; 
    marginWidth = MAX(31, MIN(45, marginWidth)); 
    return marginWidth; 
} 

@end 
0

He intentado un enfoque diferente. Pero no estoy seguro de si siempre funciona. Tenía un UITableView agrupado y necesitaba hacer una vista de encabezado personalizada. Pero como sabe, al implementar el método viewForHeader inSection no podemos determinar los márgenes para nuestra vista creada. Por lo tanto, lo que he hecho es en primer lugar agregar una propiedad CGRect de archivo ViewController .m:

@property(nonatomic)CGRect groupedCellRectangle; 

y en UITableViewDelegate:

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{ 
    static BOOL groupFrameInitialized = NO; 
    if(!groupFrameInitialized){ 
     groupFrameInitialized = YES; 
     self.groupedCellRectangle = cell.contentView.frame; 
    } 
} 

después de entonces, en mi método viewForHeader insection:

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ 
    UIView *v = [[UIView alloc] initWithFrame:CGRectMake(self.groupedCellRectangle.origin.x, 0, self.groupedCellRectangle.size.width, 28)]; 
    [v setBackgroundColor:[UIColor clearColor]]; 
    UILabel *label = [[UILabel alloc] initWithFrame:v.frame]; 
    label.text = @"KAF"; 
    [v addSubview:label]; 
    return v; 
} 

el resultado es el que supongo. groupedCellRectangle ha almacenado correctamente el valor de CGRect con margen.

La idea detrás de este enfoque fue UITableView siempre llame al método viewForHeader después de la llamada willDisplay.

Espero que ayude ...

1

margen izquierdo más precisa para la zona 'elástica' en lugar del 'APX. 6% calc. '

Nota al margen: el iPad implementa el relleno superior e inferior de la sección adicional además del relleno del margen izquierdo, es 10.0f por debajo del ancho de la tabla 400.0f y 31.0f de lo contrario.

-(CGFloat)leftMarginForTableView:(UITableView*)tableView 
{ 
    if (tableView.style != UITableViewStyleGrouped) return 0; 
    CGFloat widthTable = tableView.bounds.size.width; 
    if (isPhone)    return (10.0f); 
    if (widthTable <= 400.0f) return (10.0f); 
    if (widthTable <= 546.0f) return (31.0f); 
    if (widthTable >= 720.0f) return (45.0f); 
    return (31.0f + ceilf((widthTable - 547.0f)/13.0f)); 
} 
1

Esto es ahora accesible a través de una propiedad de UITableViewCell:

@property(nonatomic) UIEdgeInsets separatorInset 

Apple Docs - UITableViewCell - seperatorInset

+0

Y creando una subclase de UILabel ala [este método] (http: // stackoverflow.com/questions/3476646/uilabel-text-margin) utilizando en su lugar una propiedad de 'insets' que defina, puede configurar fácilmente su propia inserción en una etiqueta personalizada en' tableView: viewForHeaderInSection: 'o similar con un código como este : 'label.insets = tableview.separatorInset;' – henryaz

Cuestiones relacionadas