¿Por qué hay un relleno adicional en la parte superior de mi UITableView con el estilo UITableViewStyleGrouped en iOS7?

A partir de iOS7, hay espacio adicional en la parte superior de mi UITableView que tienen un estilo UITableViewStyleGrouped .

Aquí hay un ejemplo:

enter image description here

La vista de tabla comienza en la primera flecha, hay 35 píxeles de relleno inexplicado, luego el encabezado verde es una UIView devuelta por viewForHeaderInSection (donde la sección es 0).

¿Alguien puede explicar de dónde viene esta cantidad de 35 píxeles y cómo puedo deshacerme de ella sin cambiar a UITableViewStylePlain ?

Me ayudó lo siguiente:

YouStoryboard.storyboard> YouViewController> Atributo inspector> Desmarcar – Ajusta las inserciones de la vista de desplazamiento.

enter image description here

Jugué un poco más con esto y parece que esto es un efecto secundario de establecer tableView’s tableHeaderView = nil .

Porque mi tableView tiene un tableHeaderView apariencia dinámica, cuando necesito ocultar el tableHeaderView , en lugar de hacer self.tableView.tableHeaderView = nil; , Hago:

 self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.tableView.bounds.size.width, 0.01f)]; 

Me gusta más esta solución que establecer un contentInset.top algo arbitrario porque también uso el contentInset.top dinámicamente. Tener que recordar quitar 35px adicionales cada vez que recalculo contentInset.top es tedioso.

Para IOS 7 si está asignando una vista de tabla en un controlador de vista, puede ver

 self.edgesForExtendedLayout = UIRectEdgeNone; 

tu problema parecía similar al mío

Actualizar:

Swift en iOS 9.x:

 self.edgesForExtendedLayout = UIRectEdge.None 

Swift 3:

 self.edgesForExtendedLayout = UIRectEdge.init(rawValue: 0) 

Intente cambiar la propiedad UITableView que UITableView hereda de UIScrollView .

 self.tableView.contentInset = UIEdgeInsetsMake(-36, 0, 0, 0); 

Es una solución, pero funciona

 self.automaticallyAdjustsScrollViewInsets = NO; 

¡intenta, puedes lidiar con eso!

Puede detectar si su aplicación ejecuta iOS7 o superior y agregar estos dos métodos en su delegado de vista de tabla (generalmente en su código UIViewController)

 -(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { return CGFLOAT_MIN; } -(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { return CGFLOAT_MIN; } 

Esto tal vez no es una solución elegante pero funciona para mí

He encontrado la causa de mi error original y he creado un proyecto de muestra que lo muestra. Creo que hay un error iOS7.

A partir de iOS7, si crea un UITableView con el estilo Agrupado, pero no tiene un delegado configurado en el primer diseño, entonces establece un delegado y llama a reloadData, habrá un espacio de 35px en la parte superior que nunca desaparecerá.

Ver este proyecto que hice mostrando el error: https://github.com/esilverberg/TableViewDelayedDelegateBug

Específicamente este archivo: https://github.com/esilverberg/TableViewDelayedDelegateBug/blob/master/TableViewDelayedDelegateBug/ViewController.m

Si la línea 24 está activa,

 [self performSelector:@selector(updateDelegate) withObject:nil afterDelay:0.0]; 

habrá un espacio extra de 35 px en la parte superior. Si la línea 27 está activa y 24 está comentada,

 self.tableView.delegate = self; 

sin espacio en la parte superior. Es como que tableView está almacenando en caché un resultado en alguna parte y no se está redibujando después de que se establece el delegado y se llama a reloadData.

Desmarque “Ajustar las inserciones de la vista de desplazamiento”

enter image description here

Otro comentario rápido … incluso en XCode 6.1, hay un error con espacios verticales que aparecen en la parte superior de UIScrollViews , UITextViews y UITableViews .

enter image description here

A veces, la única forma de solucionar este problema es ir al Storyboard y arrastrar el control del problema para que ya no sea la primera subvista en la página.

enter image description here

(Mi agradecimiento a Oded por señalarme en esta dirección … Publicaré este comentario, solo para agregar algunas capturas de pantalla, para demostrar los síntomas y corregirlo).

De acuerdo con esta guía de transición para iOS7 de Apple, las inserciones de contenido de la vista de desplazamiento se ajustan automáticamente. El valor predeterminado de automaticallyAdjustsScrollViewInsets está establecido en SÍ.

El UIViewController que tiene UITableView debe establecer esta propiedad en NO.

 self.automaticallyAdjustsScrollViewInsets = NO; 

Esto hará el truco.

EDIT 1:

Además, uno podría intentarlo

 self.navigationController.navigationBar.translucent = YES; 

Esto también elimina el relleno adicional en la parte superior.

Mientras usa TableView agrupado, use esto para evitar el corte de bordes en la vista.

 self.tableView.contentInset = UIEdgeInsetsMake(-35, 0, 0, 0); 

Muchas de las respuestas anteriores son demasiado extravagantes. Se romperían en cualquier momento en el futuro si Apple decide arreglar este comportamiento inesperado.

La raíz del problema:

  1. a UITableView no le gusta tener un encabezado con una altura de 0.0. Si lo que intenta hacer es tener un encabezado con una altura de 0, puede saltar a la solución.

  2. incluso si luego asigna una altura no 0.0 a su encabezado, a UITableView no le gusta que se le asigne un encabezado con una altura de 0.0 al principio.

Solución:

Entonces, la solución más simple y confiable es asegurar que la altura de su encabezado no sea 0 cuando la asigne a su vista de tabla.

Algo como esto funcionaría:

 // Replace UIView with whatever class you're using as your header below: UIView *tableViewHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, self.tableView.bounds.size.width, CGFLOAT_MIN)]; self.tableView.tableHeaderView = tableViewHeaderView; 

Algo como esto llevaría al problema en algún momento (generalmente, después de un desplazamiento):

 // Replace UIView with whatever class you're using as your header below: UIView *tableViewHeaderView = [[UIView alloc] initWithFrame:CGRectZero]; self.tableView.tableHeaderView = tableViewHeaderView; 

Storyboard:

Solo desmarque: Adjust Scroll View Insets en las opciones de View Controller

enter image description here

Código:

 self.automaticallyAdjustsScrollViewInsets = false 

En mi caso, esto fue lo que me ayudó. Estoy apoyando ios6 también.

 if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) { self.edgesForExtendedLayout = UIRectEdgeNone; self.extendedLayoutIncludesOpaqueBars = NO; self.automaticallyAdjustsScrollViewInsets = NO; } 

Simplemente agregue lo siguiente a su viewDidLoad en su VC:

 self.automaticallyAdjustsScrollViewInsets = NO; 

Esta es la solución para iOS 10 que usa Swift 3:

Puede deshacerse de los rellenos superior e inferior implementando los siguientes métodos desde UITableViewDelegate .

  func tableView( _ tableView: UITableView, heightForHeaderInSection section: Int ) -> CGFloat { return CGFloat.leastNormalMagnitude } func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { return CGFloat.leastNormalMagnitude } 

Así que estaba probando todos los métodos aquí, y esta vez ninguno de ellos me ayudó. Mi caso fue una vista de tabla agrupada en iOS 9. Realmente no sé por qué y cómo me enteré de esto, pero para mí, se configuró tableViewHeader con una UIView con una altura mínima de 0.01 . CGRectZero no ayudó, nada realmente ayudó:

 tableView.tableHeaderView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 0.0, height: 0.01)) 

Swift: iOS Tenía tabla vista en la vista de desplazamiento … cuando hice clic en “Atrás” en la misma pantalla. La vista de desplazamiento tiene más espacio en la parte superior … para resolver esto he usado:

  self.automaticallyAdjustsScrollViewInsets = false 

Un valor booleano que indica si el controlador de vista debe ajustar automáticamente sus inserciones de vista de desplazamiento. El valor predeterminado es verdadero, lo que permite que el controlador de vista ajuste sus inserciones de vista de desplazamiento en respuesta a las áreas de pantalla consumidas por la barra de estado, la barra de navegación y la barra de herramientas o la barra de tabs. Establézcalo en falso si desea administrar los ajustes del recuadro de vista de desplazamiento usted mismo, como cuando hay más de una vista de desplazamiento en la jerarquía de vista.

Mi respuesta será más general, pero también se puede aplicar a esto.

Si la vista raíz (del ViewController ) o el primer elemento secundario (subvista) de la vista raíz es una subclase de UIScrollView (o UIScrollView), y si

 self.navigationController.navigationBar.translucent = YES; 

framework automáticamente establecerá contentInset precalculado .


Para evitar esto, puedes hacer

 self.automaticallyAdjustsScrollViewInsets = NO; 

pero en mi caso no pude hacer esto, porque estaba implementando SDK que tiene el componente UIView que pueden usar otros desarrolladores. Ese componente UIView contiene UIWebView (que tiene UIScrollView como la primera subvista). Si ese componente se agrega como el primer elemento secundario en la jerarquía de vistas de UIViewController, el sistema aplicará las inserciones automáticas.

He solucionado esto agregando vista ficticia con marco (0,0,0,0) antes de agregar UIWebView.

En este caso, el sistema no encontró la subclase de UIScrollView como la primera subvista y no aplicaba las inserciones

Gracias a la respuesta de @Aurelien Porte. Aquí está mi solución

Causa de este problema: –

  1. a UITableView no le gusta tener un encabezado con una altura de 0.0. Si lo que intenta hacer es tener un encabezado con una altura de 0, puede saltar a la solución.
  2. incluso si luego asigna una altura no 0.0 a su encabezado, a UITableView no le gusta que se le asigne un encabezado con una altura de 0.0 al principio.

En ViewDidLoad: –

 self.edgesForExtendedLayout = UIRectEdge.None self.automaticallyAdjustsScrollViewInsets = false 

No hay necesidad de algo como esto: –

 self.myTableview.contentInset = UIEdgeInsetsMake(-56, 0, 0, 0) 

En el delegado de heightForHeaderInSection : –

 if section == 0 { return 1 } else { return 40; // your other headers height value } 

En delegado viewForHeaderInSection : –

 if section == 0 { // Note CGFloat.min for swift // For Objective-c CGFLOAT_MIN let headerView = UIView.init(frame: CGRectMake(0.0, 0.0, self.myShaadiTableview.bounds.size.width, CGFloat.min)) return headerView } else { // Construct your other headers here } 

Supongo que es solo parte del nuevo estilo UITableViewStyleGrouped . Está en todas las vistas de tabla agrupadas y no parece haber ninguna forma directa de controlar ese espacio.

Si ese espacio está representado por un UIView , sería posible buscar a través de todas las subviews de UITableView para encontrar esa vista específica y editarla directamente. Sin embargo, también existe la posibilidad de que ese espacio sea solo un desplazamiento codificado antes de que se inicien los encabezados y las celdas y no haya forma de editarlo.

Para buscar a través de todas las subvistas (ejecutaría este código cuando la tabla no tenga celdas, para que sea más fácil leer el resultado):

 - (void)listSubviewsOfView:(UIView *)view { // Get the subviews of the view NSArray *subviews = [view subviews]; // Return if there are no subviews if ([subviews count] == 0) return; for (UIView *subview in subviews) { NSLog(@"%@", subview); // List the subviews of subview [self listSubviewsOfView:subview]; } } 

Tenía la misma solución que arielyz. Una vez que moví el UITableView para que no fuera la primera subvista de la vista principal, desapareció. Mi espacio era de 20 px, no de 35.

No pude recrearlo en un retrato xib, solo un paisaje xib. Voy a presentar un error de radar más adelante si puedo reproducirlo en una aplicación de demostración simple.

Creo que hacer UIEdgeInsets -35 0 0 0 es tedioso. En mi caso, implementé el método tableView: heightForHeaderInSection: y tiene el potencial de devolver 0.

Cuando cambié 0 a 0.1f, el problema simplemente desapareció.

Así es como se puede solucionar fácilmente en iOS 11 y Xcode 9.1 a través de Storyboard:

Seleccione Vista de tabla> Inspector de tamaño> Incrustos de contenido: Nunca

 override func viewWillAppear(animated: Bool) { self.edgesForExtendedLayout = UIRectEdge.None // OR self.sampleTableView.contentInset = UIEdgeInsetsMake(-64, 0, 0, 0); //OR self.automaticallyAdjustsScrollViewInsets = false } 

usar este Creo que esta ayuda …

  - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { return 0.005f;// set this according to that you want... } 
 -(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ return CGFLOAT_MIN; } 

¡Eso es todo amigos!

He estado golpeando mi cabeza contra este también. Estoy bastante seguro de que esto es un error de iOS7. Lo que me ayudó eventualmente, es el orden de las opiniones en el xib. Tenía una vista en la que la vista de tabla se mostraba correctamente y otra en la que la vista de tabla tenía ese espacio extra de 35 píxeles. La única diferencia entre entonces (UITableView sabio), es que en la mala visualización, UITableView fue el primer elemento secundario, mientras que en la vista que se mostraba correctamente, era el segundo.

Eso fue lo que hizo el truco para mí, simplemente cambiando el orden de las vistas. Realmente prefiero no agregar líneas adicionales de código para una solución alternativa …

Lo único que funcionó para mí fue:

Swift :

 tableView.sectionHeaderHeight = 0 tableView.sectionFooterHeight = 0 

Objective-C :

 self.tableView.sectionHeaderHeight = 0; self.tableView.sectionFooterHeight = 0; 

Además, todavía tenía un espacio extra para la primera sección. Eso fue porque estaba usando la propiedad tableHeaderView incorrecta. Se corrigió eso al agregar:

 self.tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.size.width, height: 0.01)) 

Tenemos múltiples respuestas para esto.

1) Puede agregar UIImageview en view didload

 UIImageView * imbBackground = [UIImageView new]; [self.view addSubview:imbBackground]; 

2) Puede establecer la altura del encabezado y pie de página 0.1

 - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { return 0.1; } - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ return 0.1; } 

3) Puede agregar vistas de encabezado y pie de página con una altura de 0.1

 tblCampaigns.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, tblCampaigns.bounds.size.width, 0.01f)]; tblCampaigns.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, tblCampaigns.bounds.size.width, 0.01f)];