Quiero cambiar el desplazamiento de la tabla cuando finaliza la carga y ese desplazamiento depende del número de celdas cargadas en la tabla.
¿De todos modos está en el SDK saber cuándo ha finalizado la carga de uitableview? No veo nada en el delegado ni en los protocolos de origen de datos.
No puedo usar el recuento de las fuentes de datos solo por la carga de las celdas visibles.
ios
iphone
uitableview
emenegro
fuente
fuente
Respuestas:
Mejora a la respuesta @RichX:
lastRow
puede ser ambos[tableView numberOfRowsInSection: 0] - 1
o((NSIndexPath*)[[tableView indexPathsForVisibleRows] lastObject]).row
. Entonces el código será:ACTUALIZACIÓN: Bueno, el comentario de @ htafoya es correcto. Si desea que este código detecte el final de la carga de todos los datos desde el origen, no lo haría, pero esa no es la pregunta original. Este código es para detectar cuándo se muestran todas las celdas que deben ser visibles.
willDisplayCell:
se usa aquí para una interfaz de usuario más fluida (una sola celda generalmente se muestra rápidamente después de lawillDisplay:
llamada). También puedes probarlo contableView:didEndDisplayingCell:
.fuente
viewForFooterInSection
método.Versión Swift 3 y 4 y 5:
fuente
Siempre uso esta solución muy simple:
fuente
[tableView numberOfRowsInSection: 0] - 1
. Debe reemplazar0
por el valor necesario. Pero ese no es el problema. El problema es que UITableView solo carga las cargas visibles. Sin embargo((NSIndexPath*)[[tableView indexPathsForVisibleRows] lastObject]).row
resuelve el problema.Aquí hay otra opción que parece funcionar para mí. En el método de delegado viewForFooter, verifique si es la sección final y agregue su código allí. Este enfoque vino a mi mente después de darse cuenta de que willDisplayCell no tiene en cuenta los pies de página si los tiene.
Creo que este enfoque funciona mejor si está buscando encontrar la carga final para todo
UITableView
, y no simplemente las celdas visibles. Dependiendo de sus necesidades, es posible que solo desee las celdas visibles, en cuyo caso la respuesta de folex es una buena ruta.fuente
nil
detableView:viewForFooterInSection:
enredado con mi diseño en iOS 7 usando Auto Layout.return CGRectMake(0,0,0,0);
self.tableView.sectionFooterHeight = 0
. De cualquier manera, parece insertar una vista de pie de página de sección con una altura de aproximadamente 10. Apuesto a que podría solucionar esto agregando una restricción de altura 0 a la vista que regreso. De todos modos, soy bueno porque realmente quería descubrir cómo iniciar UITableView en la última celda, pero vi esto primero.Solución Swift 2:
fuente
Usando API privada:
Usando API pública:
Un posible mejor diseño es agregar las celdas visibles a un conjunto, luego, cuando necesite verificar si la tabla está cargada, puede hacer un bucle for alrededor de este conjunto, por ejemplo
fuente
Para la versión de respuesta elegida en Swift 3:
Necesitaba la variable isLoadingTableView porque quería asegurarme de que la tabla se haya cargado antes de hacer una selección de celda predeterminada. Si no incluye esto, cada vez que desplace la tabla invocará su código nuevamente.
fuente
El mejor enfoque que conozco es la respuesta de Eric en: ¿ Recibir una notificación cuando UITableView haya terminado de solicitar datos?
Actualización: para que funcione tengo que poner estas llamadas
-tableView:cellForRowAtIndexPath:
fuente
Para saber cuándo una vista de tabla termina de cargar su contenido, primero debemos tener una comprensión básica de cómo se muestran las vistas en la pantalla.
En el ciclo de vida de una aplicación, hay 4 momentos clave:
Las 2 y 3 veces están totalmente separadas. Por qué ? Por razones de rendimiento, no queremos realizar todos los cálculos del momento 3 cada vez que se realiza una modificación.
Entonces, creo que te enfrentas a un caso como este:
¿Qué pasa aquí?
Como cualquier vista, una vista de tabla recarga su contenido de forma perezosa. En realidad, si llama
reloadData
varias veces, no creará problemas de rendimiento. La vista de tabla solo vuelve a calcular su tamaño de contenido en función de su implementación delegada y espera el momento 3 para cargar sus celdas. Esta vez se llama pase de diseño.Bien, ¿cómo entrar en el pase de diseño?
Durante el pase de diseño, la aplicación calcula todos los fotogramas de la jerarquía de vistas. Para involucrarse, puede anular los métodos dedicados
layoutSubviews
,updateLayoutConstraints
etc. enUIView
ay los métodos equivalentes en una subclase de controlador de vista.Eso es exactamente lo que hace una vista de tabla. Anula
layoutSubviews
y, según la implementación de su delegado, agrega o elimina celdas. LlamacellForRow
justo antes de agregar y diseñar una nueva celda,willDisplay
justo después. Si llamóreloadData
o agregó la vista de tabla a la jerarquía, la vista de tablas agrega tantas celdas como sea necesario para llenar su marco en este momento clave.Bien, pero ahora, ¿cómo saber cuándo una vista de tablas ha terminado de recargar su contenido?
Ahora podemos reformular esta pregunta: ¿cómo saber cuándo una vista de tabla ha terminado de presentar sus subvistas?
• La forma más fácil es acceder al diseño de la vista de tabla:
Tenga en cuenta que este método se llama muchas veces en el ciclo de vida de la vista de tabla. Debido al desplazamiento y al comportamiento de la vista de tabla, las celdas se modifican, eliminan y agregan con frecuencia. Pero funciona, justo después de que las
super.layoutSubviews()
células se cargan. Esta solución es equivalente a esperar elwillDisplay
evento de la última ruta de índice. Este evento se llama durante la ejecuciónlayoutSubviews
de la vista de tabla para cada celda agregada.• Otra forma es recibir una llamada cuando la aplicación finalice un pase de diseño.
Como se describe en la documentación , puede usar una opción de
UIView.animate(withDuration:completion)
:Esta solución funciona pero la pantalla se actualizará una vez entre el momento en que se realiza el diseño y el momento en que se llama al bloque. Esto es equivalente a la
DispatchMain.async
solución pero especificado.• Alternativamente, preferiría forzar el diseño de la vista de tabla
Hay un método dedicado para forzar a cualquier vista a calcular inmediatamente sus marcos de subvista
layoutIfNeeded
:Sin embargo, tenga cuidado, al hacerlo se eliminará la carga diferida utilizada por el sistema. Llamar a esos métodos repetidamente podría crear problemas de rendimiento. Asegúrese de que no se les llame antes de que se calcule el marco de la vista de la tabla, de lo contrario, la vista de la tabla se cargará nuevamente y no se le notificará.
Creo que no hay una solución perfecta. Subclasificar las clases podría conducir a problemas. Un pase de diseño comienza desde la parte superior y va hacia la parte inferior, por lo que no es fácil recibir una notificación cuando se realiza todo el diseño. Y
layoutIfNeeded()
podría crear problemas de rendimiento, etc. Pero conociendo esas opciones, debería poder pensar en una alternativa que se ajuste a sus necesidades.fuente
Así es como lo haces en Swift 3:
fuente
así es como lo hago en Swift 3
fuente
Esto es lo que haría.
En su clase base (puede ser rootVC BaseVc, etc.),
A. Escriba un protocolo para enviar la devolución de llamada "DidFinishReloading".
B. Escriba un método genérico para recargar la vista de tabla.
En la implementación del método de la clase base, llame a reloadData seguido de delegateMethod con retraso.
Confirme con el protocolo de finalización de recarga en todos los controladores de vista donde necesita la devolución de llamada.
Referencia: https://discussions.apple.com/thread/2598339?start=0&tstart=0
fuente
La respuesta de @folex es correcta.
Pero fallará si tableView tiene más de una sección mostrada a la vez.
fuente
En Swift puedes hacer algo como esto. La siguiente condición será verdadera cada vez que llegue al final de la tabla
fuente
Sé que esto se responde, solo estoy agregando una recomendación.
Según la siguiente documentación
https://www.objc.io/issues/2-concurrency/thread-safe-class-design/
Arreglar problemas de tiempo con dispatch_async es una mala idea. Sugiero que deberíamos manejar esto agregando BANDERA o algo así.
fuente
Si tiene varias secciones, aquí le mostramos cómo obtener la última fila en la última sección (Swift 3):
fuente
Accidentalmente me topé con esta solución:
Debe configurar footerView antes de obtener contentSize, por ejemplo, en viewDidLoad. Por cierto. configurar footeView le permite eliminar separadores "no utilizados"
fuente
¿Está buscando el número total de elementos que se mostrarán en la tabla o el total de elementos actualmente visibles? De cualquier manera ... Creo que el método 'viewDidLoad' se ejecuta después de que se invocan todos los métodos de origen de datos. Sin embargo, esto solo funcionará en la primera carga de datos (si está utilizando un único ViewController de asignación).
fuente
Estoy copiando el código de Andrew y expandiéndolo para tener en cuenta el caso en el que solo tiene 1 fila en la tabla. ¡Me está funcionando hasta ahora!
NOTA: Solo estoy usando 1 sección del código de Andrew, así que tenlo en cuenta.
fuente
En iOS7.0x la solución es un poco diferente. Esto es lo que se me ocurrió.
fuente
C objetivo
Rápido
fuente
UICollectionView
hasta donde yo entiendo.