iPhone: oculta la barra de búsqueda de UITableView de forma predeterminada

85

Usé Interface Builder para crear una vista de tabla, a la que agregué la barra de búsqueda de la biblioteca y el controlador de pantalla de búsqueda para agregar la funcionalidad de búsqueda. Sin embargo, IB lo configuró para que la barra sea visible en la parte superior de la pantalla cuando se muestre la vista por primera vez.

Me gustaría saber cómo hacer que la barra de búsqueda esté oculta de forma predeterminada pero que se pueda desplazar con la vista de tabla (consulte la aplicación Mail de Apple para ver un ejemplo). He intentado llamar scrollRectToVisible:animated:en viewDidLoadpara desplazarse a la vista de tabla hacia abajo, pero fue en vano. ¿Cuál es la forma preferida de ocultar la barra de búsqueda de forma predeterminada?

Tim
fuente

Respuestas:

116

Primero asegúrese de agregar UISearchBar a tableHeaderView de UITableView para que se desplace con el contenido de la tabla y no se fije en la parte superior de la vista.

La barra de búsqueda no se cuenta como una fila en la vista de tabla, por lo que si desplaza la parte superior de la vista de tabla a la primera fila, 'oculta' la barra de búsqueda:

[yourTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];

o en Swift:

yourTableView.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0), atScrollPosition: UITableViewScrollPosition.Top, animated: false)

Asegúrese de no desplazarse por la vista de tabla antes de que contenga datos ( scrollToRowAtIndexPathgenerará una excepción si la ruta de índice dada no apunta a una fila válida (es decir, si la vista de tabla está vacía)).

Zargony
fuente
12
En realidad, tengo un problema en el que la vista de la tabla no se desplaza si no hay suficientes filas para llenar la pantalla; en una tabla con una o dos filas, este código no hace nada. ¿Es ese el comportamiento esperado? ¿Puedo evitarlo de alguna manera?
Tim
18
Encontré una manera: en lugar de desplazarse a una ruta de índice, cambie el desplazamiento de contenido de la vista de desplazamiento de la tabla a un CGRect en 0.0, 44.0
Tim
107
Tim, ¡ese es el camino a seguir! Usé self.tableView.contentOffset = CGPointMake (0, self.searchDisplayController.searchBar.frame.size.height);
Joe D'Andrea
1
Por cierto, cuando estaba ingresando este código después de una llamada a [tableView reloadData] que hizo que mi tabla pasara de 2 filas a suficientes filas para permitir el desplazamiento normal, descubrí que el uso del método contentOffset causaba una visualización desigual y un ocultamiento de la búsqueda box mientras usaba el método scrollToRowAtIndexPath no tenía las mismas sacudidas.
Chris R
1
Esta es la única forma definitiva que funciona en CUALQUIER circunstancia. La configuración contentOffsetcon cualquier valor se romperá si está empleando un diseño complejo de controlador de vista. No lo recomiendo.
eonil
45

No agregue UISearchBar como una subvista de UITableView, esto no es necesario.

UITableView tiene una propiedad tableHeaderView que es perfecta para esto:

- (void) viewDidLoad {
    [super viewDidLoad]; 
    self.searchBar = [[[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)] autorelease];
    self.searchBar.showsCancelButton = YES;    
    self.searchBar.delegate = self;
    self.tableView.tableHeaderView = self.searchBar;     
}

Si no quiere verlo por defecto:

- (void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self.tableView setContentOffset:CGPointMake(0, 44)];
}

También obtengo el botón cancelar para ocultarlo nuevamente .... (y quitar el teclado)

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
    [self.tableView setContentOffset:CGPointMake(0, 44) animated:YES];
    [self.searchBar resignFirstResponder];
}
bandejapaisa
fuente
Para mí, esta fue la única solución que produjo una implementación oculta de UISearchBar que parecía estar en línea con el HIG. Las otras soluciones en las que está "pegado" en la parte superior de la vista de la mesa no parecen naturales.
kurtzmarc
1
Esta solución funcionó mejor. Esta debería ser la respuesta en mi opinión.
darwindeeds
Esta solución es buena (+1). Sin embargo, tableView no oculta la barra de búsqueda correctamente en algunos casos (en mi caso: cuando el controlador de tableview se rechaza desde otro controlador de vista). Hay una pregunta sobre este problema: stackoverflow.com/questions/15222186/… Sin embargo , creo que la respuesta proporcionada a esta pregunta no es del todo buena. @bandejapaisa, ¿tienes alguna idea?
Brian
3
Esto funcionó bien para mí, aunque en lugar de codificar 44 en todo momento, sugiero usar self.tableView.tableHeaderView.frame.size.height en viewWillAppear para permitir los cambios que Apple pueda hacer en el futuro en la altura de la barra de búsqueda.
John Stephen
poner esto viewWillAppeares una mala idea porque se ejecutará cada vez que navegue de regreso a su vista. Esto significa que la vista de la mesa se reducirá lentamente. ¡Insecto irritante!
Sirens
25

El contentOffset se señaló en los comentarios de Tim y Joe D'Andrea, pero esto se amplió un poco al agregar una animación para ocultar la barra de búsqueda. Noté que es un poco inesperado que la barra de búsqueda simplemente desaparezca.

Una pequeña actualización para aquellos que quieren apuntar a iOS 4.0 y superior, intente esto:

[UIView animateWithDuration:0.4 animations:^{
    self.tableView.contentOffset = CGPointMake(0, self.searchDisplayController.searchBar.frame.size.height);
 } completion:nil];

Respuesta anterior:

[UIView beginAnimations:@"hidesearchbar" context:nil];
[UIView setAnimationDuration:0.4];
[UIView setAnimationBeginsFromCurrentState:YES];

self.tableView.contentOffset = CGPointMake(0, self.searchDisplayController.searchBar.frame.size.height);

[UIView commitAnimations];

Andrei
fuente
9
Descubrí que la animación es la clave de esta solución. Intentar establecer el desplazamiento de contenido sin la animación parecerá no hacer nada. Sin embargo, en lugar de usar los métodos de animación (o bloques) en esta muestra, encuentro que simplemente llamar a [self.tableView setContentOffset: CGPointMake (0,44) animated: TRUE] funciona bastante bien.
quickthyme
Parece que no funciona en absoluto sin la animación. @quickthyme ha hecho la misma observación.
Thilo
5
He tenido éxito con esto sin necesitar las animaciones si lo implementa en viewDidAppear:lugar de viewDidLoad.
wbyoung
8

Hay muchas respuestas a esta solución, sin embargo, ninguna funcionó muy bien para mí.

Esto funciona perfectamente. Sin animación, y está hecho sobre-viewDidLoad

 - (void)viewDidLoad {
     [super viewDidLoad];
     self.tableView.contentOffset = CGPointMake(0,  self.searchBar.frame.size.height - self.tableView.contentOffset.y);
 }

Nota:

El código asume que tiene el searchBar @propertyque está vinculado a la barra de búsqueda. Si no, puedes usar self.searchDisplayController.searchBaren su lugar

Matej
fuente
este es el único que funcionó para mí! , pero solo descarga la descarga ... así que la primera vez se oculta, pero luego ya no se oculta mientras se ejecuta la aplicación. Y traté de ponerlo en viewwillaparear y viewdidappear pero funciona mal. ¡Gracias!
fguespe
@fguespe eso es extraño .. Se debe llamar a viewDidLoad cada vez que se crea una instancia de la vista. Nunca me pasó que el UISearchBar fuera visible después de regresar de otra vista.
Matej
Estoy usando una aplicación con pestañas. ¿Tal vez eso?
fguespe
@fguespe Veo que ese podría ser el problema hmm. Desafortunadamente, no estoy seguro de cómo resolvería eso si -viewWillAppearno funciona. ¿Se llama cuando el controlador de pestañas cambia a la vista?
Matej
viewwillappear y viewdidappear se llaman, pero lo intenté con ambos y la vista es incorrecta. No devuelve el resultado esperado. Quiero decir, algo lo hace, pero lo hace mal.
fguespe
7

Para Swift 3+

Hice esto:

Declare esto var:

    var searchController = UISearchController()

Y en el viewDidLoad()metodo

    searchController = UISearchController(searchResultsController: nil)
    searchController.searchResultsUpdater = self
    searchController.hidesNavigationBarDuringPresentation = false
    searchController.dimsBackgroundDuringPresentation = true
    searchController.searchBar.placeholder = NSLocalizedString("Search", comment: "")
    definesPresentationContext = true
    tableView.tableHeaderView = searchController.searchBar

    tableView.contentOffset = CGPoint(x: 0, y: searchController.searchBar.frame.size.height)
Dasoga
fuente
5

Mi objetivo era ocultar la barra de búsqueda agregada a tableHeaderView del estilo simple de TableView en el guión gráfico cuando se carga el controlador de vista y mostrar la barra cuando el usuario se desplaza hacia abajo en la parte superior de UITableView. Entonces, estoy usando Swift y he agregado una extensión:

extension UITableView {
    func hideSearchBar() {
        if let bar = self.tableHeaderView as? UISearchBar {
            let height = CGRectGetHeight(bar.frame)
            let offset = self.contentOffset.y
            if offset < height {
                self.contentOffset = CGPointMake(0, height)
            }
        }
    }
}

en viewDidLoad () simplemente llame:

self.tableView.hideSearchBar()
HotJard
fuente
5

Todas las soluciones existentes no funcionan para mí en iOS 8 cuando no hay suficientes filas para llenar el tableView ya que iOS ajustará el recuadro automáticamente en esta situación. (Sin embargo, las respuestas existentes son buenas cuando hay suficientes filas)

Después de perder como 6 horas en este tema, finalmente obtuve esta solución.

En resumen, debe insertar celdas vacías en tableView si no hay suficientes celdas, por lo que el tamaño del contenido de tableView es lo suficientemente grande como para que iOS no ajuste el recuadro por usted.

Así es como lo hice en Swift:

1.) declarar una variable minimumCellNumcomo propiedad de clase

var minimumCellNum: Int?

2.) Calcular minimumCellNumy un conjunto tableView.contentOffsetdeviewWillAppear

let screenHeight = Int(UIScreen.mainScreen().bounds.height)

// 101 = Height of Status Bar(20) + Height of Navigation Bar(44) + Height of Tab Bar(49)
// you may need to subtract the height of other custom views from the screenHeight. For example, the height of your section headers.
self.minimumCellNum = (screenHeight - 103 - heightOfOtherCustomView) / heightOfYourCell
self.tableView.contentOffset = CGPointMake(0, 44)

3 en tableView(tableView: UITableView, numberOfRowsInSection section: Int))

let numOfYourRows = YOUR LOGIC
if numOfYourRows > minimumCellNum {
    return numOfYourRows
} else {
    return minimumCellNum!
}

4.) Registre una celda vacía, cuyo selectionatributo es None, en el guión gráfico y entableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath)

if indexPath.row < numOfYourRows {
    return YOUR CUSTOM CELL
} else {
    let cell = tableView.dequeueReusableCellWithIdentifier("EmptyCell", forIndexPath: indexPath) as! UITableViewCell
    return cell
}

5.) en tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)

if tableView == self.tableView {
    if numOfYourRows < (indexPath.row + 1) {
        return
    }
    YOUR LOGIC OF SELECTING A CELL
}

Esta no es una solución perfecta, pero es la única solución que realmente funciona para mí en iOS 8. Me gustaría saber si existe una solución más ordenada.

Brian
fuente
Tuve que hacer esto para iOS 11. La configuración de contentOffset solo funcionó para iOS 9/10 para 0 o más celdas, y también funcionó en iOS 11 para 8+ celdas. Cualquier cosa menos requería esta solución. ¿Hay alguna razón por la que?
Tony
Creo que el primer párrafo de esta publicación explica por qué.
Brian
Entendí el primer párrafo, pero todavía era extraño que solo estuviera "roto" en iOS 11 para mí. Hubiera esperado un comportamiento similar para iOS 9, 10 y 11 cuando el número de celdas es el mismo (menos que suficiente). Gracias de nuevo y perdón por traer una publicación antigua.
Tony
4

Nada de lo anterior funcionó para mí, así que en caso de que alguien tenga el mismo problema.

Lo he searchBarconfigurado como tableHeaderViewen una tabla agrupada en iOS7. En viewDidLoadtengo tableView.contentOffset = CGPointMake(0, 44);que mantener searchBarinicialmente "escondido". Cuando el usuario se desplaza hacia abajo searchBarse visualiza

Objetivo: ocultar la barra de búsqueda al tocar el botón cancelar

En searchBarCancelButtonClicked(searchBar: UISearchBar!)

Esto no funcionó: [yourTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO]; tableView se estaba desplazando demasiado hacia arriba, lo que provocó que la fila 0 fuera detrás de toolBar.

Esto no funcionó: tableView.ContentOffset = CGPointMake(0, 44) - no pasa nada

Esto no funcionó: tableView.ContentOffset = CGPointMake(0, searchBar.frame.size.height) - no pasa nada

Esto no funcionó: tableView.setContentOffset(CGPointMake(0, 44), animated: true); nuevamente tableView se estaba desplazando demasiado hacia arriba, lo que resultó en que la fila 0 fuera detrás de toolBar.

Esto funcionó parcialmente: tableView.setContentOffset(CGPointMake(0, 0) pero titleForHeaderInSectioniba detrás de toolBar

ESTO FUNCIONÓ: tableView.setContentOffset(CGPointMake(0, -20)

No parece lógico, pero solo -20 lo movió a la posición correcta

grep
fuente
Realmente no debería codificar sus puntos, ¿por qué no los usa CGRectGetHeight(searchBar.bounds)?
Zorayr
Supongo que debe hacerlo en viewDidLoad () / init () donde no se ha establecido ningún marco para que obtenga la altura de la barra de búsqueda. Quizás deberías probar con viewDidLayoutSubviews ()
Kaushil Ruparelia
Si tableView no ha terminado de cargarse, ninguna de las ContentOffsetsoluciones funcionará
Maor
4

El desplazamiento de contenido es el camino a seguir, pero no funciona el 100% del tiempo.

No funciona si se establece estimatedRowHeighten un número fijo. Todavía no conozco el trabajo. Creé un proyecto que muestra los problemas y creé un radar con Apple.

Consulte el proyecto si quiere un ejemplo rápido de cómo configurarlo todo.

RyanJM
fuente
1
¡Gracias! Esto era lo que estaba buscando. Necesitas subir mucho.
user2387149
3

Tenga en cuenta que la respuesta aceptada se bloqueará si no hay datos en la vista de tabla. Y agregarlo a viewDidLoad puede no funcionar bajo ciertas circunstancias.

[yourTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO]; // crashes if no rows/data

Por lo tanto, en su lugar, agregue esta línea de código:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    [yourTableView setContentOffset:CGPointMake(0, self.searchDisplayController.searchBar.frame.size.height)];
}
usuario3246173
fuente
2

Honestamente, ninguna de las respuestas realmente resolvió el problema (para mí). Si su vista de tabla no tiene filas O la altura de la fila es diferente, estas respuestas no son suficientes.

Lo único que funciona:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    self.tableView.contentOffset = (CGPoint){.y =  self.tableView.contentOffset.y + self.searchController.searchBar.frame.size.height};
}
p0lAris
fuente
Buena solución para el problema de la compensación. Funciona para mí cuando uso un UINavigationController.
Andreas Kraft
1
La solución no funciona cuando el número de filas no cubre toda la pantalla. ¿Sabría una solución alternativa para esto?
Zorayr
No estoy seguro de entender esto completamente. Esto funciona para mí cuando solo tengo unas pocas filas en la tabla. Sin embargo yo uso la siguiente: self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];.
p0lAris
2

El scrollToRowAtIndexPathmétodo provoca un bloqueo si no hay filas en la tabla.

Sin embargo, UITableView es solo una vista de desplazamiento, por lo que simplemente puede cambiar el desplazamiento del contenido.

Esto verifica que tenga algo como su tableHeaderView, y asumiendo que hace desplazamientos para ocultarlo

    if let searchHeight = tableView.tableHeaderView?.frame.height {
        tableView.setContentOffset(CGPoint.init(x: 0, y:searchHeight ), animated: false)
    }
Vorlon confundido
fuente
1

Encuentro que la aplicación "Notas" no puede buscar elementos cuando tableView está en blanco. Así que creo que -(void)addSubview:(UIView *)viewal principio solo se usa para agregar una tabla en blanco. Cuando agrega un elemento a su matriz de origen de datos, ejecutará otro fragmento de código para cargar tableView.

Entonces mi solución es:

if([self.arrayList count] > 0)
{
     [self.tableView reloadData];     //use jdandrea's code to scroll view when cell==nil in cellForRowAtIndexPath
     self.tableView.scrollEnabled = YES;
}
else
{
     tableBlank = [[UITableView alloc]initWithFrame:CGRectMake(0,0,320,416) style:UITableViewStylePlain] autorelease];
     tableBlank.delegate = self;
     tableBlank.dataSource = self;
     [self.view addSubview:tableBlank];
}

Espero que esto ayude :-)

Frío Zhong
fuente
1

Cambie los límites de tableView, esto se puede hacer dentro y viewDidLoadademás no tiene que preocuparse por si la tabla está vacía o no (para evitar la excepción).

CGRect newBounds = self.tableView.bounds;
newBounds.origin.y = newBounds.origin.y + self.searchBar.bounds.size.height;
self.tableView.bounds = newBounds;

Una vez que el usuario se haya desplazado hacia abajo en la tabla, la barra de búsqueda aparecerá y se comportará normalmente.

Hombre ligero
fuente
1

Las otras respuestas a esta pregunta no funcionaron en absoluto para mí, tuvieron un comportamiento extraño cuando tableView tenía 0 filas, o estropearon la posición de desplazamiento al ir y venir entre los elementos de línea principales y anidados. Esto funcionó para mí (el objetivo es ocultar el UISearchBar cuando está en carga):

public override func viewWillAppear(animated: Bool) {        
    if self.tableView.contentOffset.y == 0 {
        self.tableView.contentOffset = CGPoint(x: 0.0, y: self.searchBar.frame.size.height) 
    }
}

Explicación
En cualquier momento tableViewque aparezca, este código verifica si UISearchBar está visible (es decir, la yposición de contentOffset, también conocida como posición de desplazamiento, es 0). Si es así, simplemente se desplaza hacia abajo en la altura de la barra de búsqueda. Si la barra de búsqueda no está visible (piense en una lista más grande de elementos tableView), entonces no intentará desplazarse tableView, ya que esto estropearía la posición cuando regrese de una línea de pedido anidada.

Nota al
margen Recomendaría poner este código en un método separado para garantizar una responsabilidad única y darle la posibilidad de volver a utilizarlo en cualquier momento en su código.

kbpontius
fuente
1

Si su tabla siempre tendrá al menos una fila, simplemente desplácese hasta la primera fila de la tabla y la barra de búsqueda se ocultará automáticamente.

let firstIndexPath = NSIndexPath(forRow: 0, inSection: 0)

self.tableView.selectRowAtIndexPath (firstIndexPath, animado: falso, scrollPosition: .Top)

Si coloca el código anterior en viewDidLoad , arrojará un error porque tableView aún no se ha cargado, por lo que debe ponerlo en viewDidAppear porque en este punto el tableView ya se ha cargado.

Si lo pones en viewDidAppear , cada vez que abras tableView, se desplazará hacia la parte superior.

Tal vez no desee este comportamiento si tableView permanece abierto, como cuando es un controlador de vista UITabBar o cuando hace una transición y luego regresa. Si solo desea que se desplace hacia la parte superior en la carga inicial, puede crear una variable para verificar si es una carga inicial para que se desplace hacia la parte superior solo una vez.

Defina primero una variable llamada isInitialLoad en la clase del controlador de vista y configúrela como "verdadero":

var isInitialLoad = true

Luego verifique si isInitialLoad es verdadero en viewDidAppear y si es verdadero, desplácese hasta la parte superior y establezca la variable isInitialLoad en falso:

if isInitialLoad {
            let firstIndexPath = NSIndexPath(forRow: 0, inSection: 0)
            self.tableView.selectRowAtIndexPath(firstIndexPath, animated: false, scrollPosition: .Top)

            isInitialLoad = false
        }
drdrdrdr
fuente
1

El siguiente código me funciona

self.tableView.contentOffset = CGPointMake(0.0, 44.0);
Ashu
fuente
1

Intenté configurar el desplazamiento de contenido y scrollToIndexpath pero nada funcionó satisfactoriamente. Eliminé la configuración de tableHeaderView como searchBar de viewDidLoad y la configuré en scrollview delegate como se muestra a continuación

override func scrollViewWillBeginDragging(scrollView: UIScrollView) {
    if scrollView.contentOffset.y < 0 && tableView.tableHeaderView == nil {
        tableView.tableHeaderView = searchController.searchBar
        tableView.setContentOffset(CGPointMake(0, scrollView.contentOffset.y + searchController.searchBar.frame.size.height), animated: false)
    }
}

Esto funcionó a las mil maravillas La configuración de desplazamiento de contenido es para un desplazamiento suave

Abdur Rahman
fuente
0

No olvide tener en cuenta la barra de estado y la barra de navegación . Mi controlador de vista de tabla está integrado en un controlador de navegación, en viewDidAppear:

tableView.contentOffset = CGPointMake(0, -20) // -20 = 44 (search bar height) - 20 (status bar height) - 44 (navigation bar height)

trabajó para mi.

fujianjin6471
fuente
0

Para Swift:

Simplemente haga que el contenido de la vista de tabla y el desplazamiento, que debería ser como la altura de la barra de búsqueda.

self.tableView.contentOffset = CGPointMake(0, self.searchController.searchBar.frame.size.height)
stakahop
fuente
0

Swift 3

¡También funciona con mesa vacía!

En mi entorno, cargo celdas personalizadas por archivo xib y rowHeight se configura automáticamente.

    override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        self.tableView.contentOffset = CGPoint(x: 0, y: self.tableView.contentOffset.y + self.searchController.searchBar.bounds.height)
}
Juan
fuente
0

Tuve un problema similar. Y la única forma que encontré para resolver este problema fue usar el observador de valor clave en la propiedad contentOffset de UITableView.

Después de algunas depuraciones, me di cuenta de que el problema aparece solo si el tamaño del contenido de la vista de tabla es menor que la vista de tabla. Comienzo KVO cuando estoy en viewWillAppear. Y el envío detiene KVO 0.3 segundos después de que aparezca la vista. Cada vez que contentOffset se convirtió en 0.0, KVO reacciona y establece contentOffset en la altura de la barra de búsqueda. Dejo de KVO asincrónico después de 0.3 segundos porque el diseño de la vista restablecerá contentOffset incluso después de que aparezca la vista.

- (void)viewWillAppear:(BOOL)animated {
  [super viewWillAppear:animated];
  [self.tableView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
}

-(void)viewDidAppear:(BOOL)animated{
   __weak typeof (self) weakSelf = self;
   dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    [weakSelf.tableView removeObserver:self forKeyPath:@"contentOffset"];});
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
    if ([keyPath isEqualToString:@"contentOffset"] && self.tableView.contentOffset.y == 0.0) {
       self.tableView.contentOffset = CGPointMake(0, CGRectGetHeight(self.tableView.tableHeaderView.frame));
    }
}

-(void)dealloc {
    [self.tableView removeObserver:self forKeyPath:@"contentOffset"];
}
eslobodanos
fuente