UITableView con encabezados de sección fija


106

Saludos, estoy leyendo que el comportamiento predeterminado de UITableViewes fijar filas de encabezado de sección en la parte superior de la tabla a medida que se desplaza por las secciones hasta que la siguiente sección empuja la fila de la sección anterior fuera de la vista.

Tengo un UITableViewinterior a UIViewControllery este no parece ser el caso.

¿Es ese el comportamiento predeterminado UITableViewController?

Aquí hay un código simplificado basado en lo que tengo. Mostraré la UIControllerinterfaz y cada método de vista de tabla que he implementado para crear la vista de tabla. Tengo una clase de fuente de datos auxiliar que me ayuda a indexar mis objetos para usarlos con la tabla.

    @interface MyUIViewController ()<UITableViewDelegate, UITableViewDataSource>
        @property (nonatomic, readonly) UITableView *myTableView;
        @property (nonatomic, readonly) MyCustomHelperDataSource *helperDataSource;
    @end

    //when section data is set, get details for each section and reload table on success
    - (void)setSectionData:(NSArray *)sections {
        super.sectionData = sections; //this array drives the sections

        //get additional data for section details
        [[RestKitService sharedClient] getSectionDetailsForSection:someId 
        success:^(RKObjectRequestOperation *operation, RKMappingResult *details) {
            NSLog(@"Got section details data");
            _helperDataSource = [[MyCustomHelperDataSource alloc] initWithSections:sections andDetails:details.array];
            [myTableView reloadData];
        } failure:^(RKObjectRequestOperation *operation, NSError *error) {
            NSLog(@"Failed getting section details");
        }];
    }

    #pragma mark <UITableViewDataSource, UITableViewDelegate>

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
        if (!_helperDataSource) return 0;
        return [_helperDataSource countSectionsWithDetails]; //number of section that have details rows, ignore any empty sections
    }

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        //get the section object for the current section int
        SectionObject *section = [_helperDataSource sectionObjectForSection:section];
        //return the number of details rows for the section object at this section
        return [_helperDataSource countOfSectionDetails:section.sectionId];
    }

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

        UITableViewCell * cell;

        NSString *CellIdentifier = @"SectionDetailCell";

        cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
            cell.textLabel.font = [UIFont systemFontOfSize:12.0f];
        }

        //get the detail object for this section
        SectionObject *section = [_helperDataSource sectionObjectForSection:indexPath.section]; 

        NSArray* detailsForSection = [_helperDataSource detailsForSection:section.sectionId] ;
        SectionDetail *sd = (SectionDetail*)[detailsForSection objectAtIndex:indexPath.row];

        cell.textLabel.text = sd.displayText;
        cell.detailTextLabel.text = sd.subText;
        cell.detailTextLabel.textColor = [UIColor blueTextColor];

        return cell;
    }

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 50.0f;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return 30.0f;
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger) section {
    //get the section object for the current section
    SectionObject *section = [_helperDataSource sectionObjectForSection:section]; 

    NSString *title = @"%@ (%d)";

    return [NSString stringWithFormat:title, section.name, [_helperDataSource countOfSectionDetails:section.sectionId]];
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 260, 0)];
    header.autoresizingMask = UIViewAutoresizingFlexibleWidth;

    header.backgroundColor = [UIColor darkBackgroundColor];

    SSLabel *label = [[SSLabel alloc] initWithFrame:CGRectMake(3, 3, 260, 24)];
    label.font = [UIFont boldSystemFontOfSize:10.0f];
    label.verticalTextAlignment = SSLabelVerticalTextAlignmentMiddle;
    label.backgroundColor = [UIColor clearColor];
    label.text = [self tableView:tableView titleForHeaderInSection:section];
    label.textColor = [UIColor whiteColor];
    label.shadowColor = [UIColor darkGrayColor];
    label.shadowOffset = CGSizeMake(1.0, 1.0);
    [header addSubview:label];

    return header;
}

Eso debería funcionar. Muestre algún código.
Matthias Bauch

Esa es una forma completamente buena de usar un UITableView y debería funcionar con los encabezados. ¿Qué no están haciendo los encabezados en su caso?
Eric

@Eric los encabezados se desplazan con las filas. No se detienen en la parte superior de la mesa mientras me desplazo. Agregué el código que estoy usando para generar mi vista de tabla. Es un UITableView dentro de un UIViewController.
topwik

Respuestas:


304

Los encabezados solo permanecen fijos cuando la UITableViewStylepropiedad de la tabla se establece en UITableViewStylePlain. Si lo tiene configurado en UITableViewStyleGrouped, los encabezados se desplazarán hacia arriba con las celdas.


3
mi estilo de vista de tabla es UITableViewStylePlain, pero también se desplaza hacia arriba con las celdas.
yudun1989

8
Hay un par de posibles explicaciones para esto. Una nota importante es que los encabezados solo permanecerán fijos para las celdas dentro de su sección. Entonces, si tiene un encabezado en la sección 0, no permanecerá fijo para las celdas en la sección 1. Otra posible explicación es que no está inicializando su UITableView con el estilo adecuado. Se recomienda que lo use initWithStyle:UITableViewStylePlain, ya que llamar a algo como tableView.style = UITableViewStylePlain no funcionará.
bachonk

UITableViewStyleGrouped hace que el encabezado / pie de página sea fijo con otras celdas, mientras que UITableViewStylePlain hace que el encabezado / pie de página "flote" cuando el encabezado / pie de página alcanza la parte superior / inferior de la vista de tabla.
StoneLam

@bachonk Estoy usando una vista de encabezado extensible. y mi estilo es UITableViewStyleGrouped. Quiero arreglar el encabezado cuando me desplazo hacia arriba. si lo hago UITableViewStylePlain, entonces el encabezado se está arreglando en el medio de la pantalla, quiero desplazar el encabezado hacia abajo, pero al desplazarme hacia arriba quiero que se arregle en la primera fila ... ¿es posible?
Desarrollador Gorib

2

Cambie su estilo TableView:

self.tableview = [[UITableView alloc] initwithFrame: estilo de marco: UITableViewStyleGrouped];

Según la documentación de Apple para UITableView:

UITableViewStylePlain: una vista de tabla simple. Los encabezados o pies de página de las secciones se muestran como separadores en línea y flotan cuando se desplaza la vista de tabla.

UITableViewStyleGrouped: una vista de tabla cuyas secciones presentan distintos grupos de filas. Los encabezados y pies de página de las secciones no flotan.

Espero que este pequeño cambio te ayude.


2
esto parece ser exactamente lo contrario de lo que solicitó la pregunta, debería ser Plain, noGrouped
CupawnTae

1

Swift 3.0

Cree un ViewController con los protocolos UITableViewDelegate y UITableViewDataSource . Luego cree un tableView dentro de él, declarando que su estilo es UITableViewStyle.grouped . Esto arreglará los encabezados.

lazy var tableView: UITableView = {
    let view = UITableView(frame: UIScreen.main.bounds, style: UITableViewStyle.grouped)
    view.delegate = self
    view.dataSource = self
    view.separatorStyle = .none
    return view
}()

0

También puede establecer la propiedad de rebotes de tableview en NO. Esto mantendrá los encabezados de sección no flotantes / estáticos, pero también perderá la propiedad de rebote de la vista de tabla.


0

para que el encabezado de las secciones de UITableView no sea pegajoso o pegajoso:

  1. cambie el estilo de la vista de la tabla - hágalo agrupado para que no sea pegajoso y déjelo claro para los encabezados de sección pegajosos - no lo olvide: puede hacerlo desde el guión gráfico sin escribir código. (haga clic en la vista de su tabla y cambie su estilo desde el menú lateral derecho / componente)

  2. Si tiene componentes adicionales, como vistas personalizadas, etc., compruebe los márgenes de la vista de tabla para crear el diseño adecuado. (como la altura del encabezado para las secciones y la altura de la celda en la ruta del índice, secciones)


-2

Ahora su vista de tabla parece un estilo de tabla simple, pero no flote, sino que el estilo de tabla de configuración se establece en grupo.

[_tableView setBackgroundView:nil];
_tableView.backgroundColor = [UIColor whiteColor];
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.