UITableView
establecido en celdas estáticas.
¿Es posible ocultar algunas de las células mediante programación?
ios
objective-c
uitableview
Shmidt
fuente
fuente
IBOutletCollection
pero no veo cómo eso marcaría la diferencia. Solo descargué el código ayer, así que no creo que sea una versión antigua.Para ocultar celdas estáticas en UITable:
En su clase delegada del controlador UITableView:
C objetivo:
Rápido:
Se llamará a este método para cada celda en la UITable. Una vez que lo llama para la celda que desea ocultar, establecemos su altura en 0. Identificamos la celda objetivo creando una salida para ella:
fuente
ClipToBounds
problema, también puede configurar la celda como oculta. Esto me parecería más limpio. ;-)La mejor manera es como se describe en el siguiente blog http://ali-reynolds.com/2013/06/29/hide-cells-in-static-table-view/
fuente
Mi solución va en una dirección similar a la de Gareth, aunque hago algunas cosas de manera diferente.
Aquí va:
1. Ocultar las celdas
No hay forma de ocultar directamente las celdas.
UITableViewController
es la fuente de datos que proporciona las celdas estáticas, y actualmente no hay forma de decirle "no proporcione la celda x". Entonces tenemos que proporcionar nuestra propia fuente de datos, que delega enUITableViewController
para obtener las celdas estáticas.Lo más fácil es subclasificar
UITableViewController
y anular todos los métodos que deben comportarse de manera diferente al ocultar celdas .En el caso más simple (tabla de sección única, todas las celdas tienen la misma altura), esto sería así:
Si su tabla tiene varias secciones, o las celdas tienen diferentes alturas, debe anular más métodos. Aquí se aplica el mismo principio: debe compensar indexPath, section y row antes de delegar a super.
También tenga en cuenta que el parámetro indexPath para métodos como
didSelectRowAtIndexPath:
será diferente para la misma celda, dependiendo del estado (es decir, el número de celdas ocultas). Por lo tanto, probablemente sea una buena idea compensar siempre cualquier parámetro indexPath y trabajar con estos valores.2. Animar el cambio
Como ya dijo Gareth, obtienes fallas importantes si animas los cambios usando
reloadSections:withRowAnimation:
método.Descubrí que si llamas
reloadData:
inmediatamente después, la animación mejora mucho (solo quedan pequeños fallos). La tabla se muestra correctamente después de la animación.Entonces, lo que estoy haciendo es:
fuente
numberOfRowsInSection:
solo se llama cuando la tabla se carga por primera vez. Cuando llamo a [self.tableView reloadData],numberOfRowsInSection:
nunca se vuelve a llamar. SolocellForRowAtIndexPath:
se llama. ¿Qué me estoy perdiendo?cellOneOutlet.hidden = true
ahora anule el método a continuación, verifique qué estado de celda está oculto y devuelva la altura 0 para esas celdas. Esta es una de las muchas formas en que puede ocultar cualquier celda en tableView estático de forma rápida.
fuente
let tableViewCell = super.tableView(tableView,cellForRowAtIndexPath: indexPath)
. Supongo que se reemplaza porlet tableViewCell = tableView.cellForRow(at: indexPath as IndexPath)
.UITableViewController
, no tengo ningúnUITableView
método de delegado. Para que llameheightForRow
, ¿necesito también otros métodos?Se me ocurrió una alternativa que en realidad oculta secciones y no las elimina. Intenté el enfoque de @ henning77, pero seguí teniendo problemas cuando cambié el número de secciones del UITableView estático. Este método me ha funcionado muy bien, pero principalmente estoy tratando de ocultar secciones en lugar de filas. Estoy eliminando algunas filas sobre la marcha con éxito, pero es mucho más complicado, por lo que he tratado de agrupar las cosas en secciones que necesito mostrar u ocultar. Aquí hay un ejemplo de cómo estoy ocultando secciones:
Primero declaro una propiedad NSMutableArray
En viewDidLoad (o después de haber consultado sus datos) puede agregar secciones que desea ocultar a la matriz.
Luego implemente los siguientes métodos de delegado de TableView
Luego configure la altura del encabezado y pie de página en 1 para las secciones ocultas porque no puede establecer la altura en 0. Esto provoca un espacio adicional de 2 píxeles, pero podemos compensarlo ajustando la altura del siguiente encabezado visible.
Luego, si tiene filas específicas para ocultar, puede ajustar numberOfRowsInSection y qué filas se devuelven en cellForRowAtIndexPath. En este ejemplo, aquí tengo una sección que tiene tres filas donde tres pueden estar vacías y deben eliminarse.
Use este offsetIndexPath para calcular el indexPath para las filas donde está eliminando condicionalmente las filas. No es necesario si solo está ocultando secciones
Hay muchos métodos para anular, pero lo que me gusta de este enfoque es que es reutilizable. Configure la matriz hiddenSections, agréguela y ocultará las secciones correctas. Ocultando las filas es un poco más complicado, pero posible. No podemos simplemente establecer el alto de las filas que queremos ocultar a 0 si estamos usando un UITableView agrupado porque los bordes no se dibujarán correctamente.
fuente
NSMutableSet
para en suhiddenSections
lugar. Es mucho más rápido ya que en su mayoría está probando la membresía.NSMutableSet
forhiddenSections
, aunque entiendo que el punto de su respuesta fue más conceptual que selectivo sobre qué tipo de estructura de datos debe usar.Resulta que puede ocultar y mostrar celdas en un UITableView estático, y con animación. Y no es tan difícil de lograr.
Proyecto de demostración
Video de demostración del proyecto
La esencia:
Use tableView:heightForRowAtIndexPath:
para especificar las alturas de las celdas dinámicamente en función de algún estado.tableView.beginUpdates();tableView.endUpdates()
tableView.cellForRowAtIndexPath:
dentrotableView:heightForRowAtIndexPath:
. Use indexPaths en caché para diferenciar las celdas.Más información en mi blog (idioma ruso)
fuente
Sí, definitivamente es posible, aunque estoy luchando con el mismo problema en este momento. Me las arreglé para ocultar las celdas y todo funciona bien, pero actualmente no puedo hacer que la cosa se anime claramente. Esto es lo que he encontrado:
Estoy ocultando filas en función del estado de un interruptor de ENCENDIDO / APAGADO en la primera fila de la primera sección. Si el interruptor está ENCENDIDO, hay 1 fila debajo de él en la misma sección; de lo contrario, hay 2 filas diferentes.
Tengo un selector llamado cuando se cambia el interruptor, y configuro una variable para indicar en qué estado estoy. Luego llamo:
Anulo la función tableView: willDisplayCell: forRowAtIndexPath: y si se supone que la celda está oculta, hago esto:
Eso oculta la celda y su contenido, pero no elimina el espacio que ocupa.
Para eliminar el espacio, anule la tabla view: heightForRowAtIndexPath: y devuelva 0 para las filas que deberían estar ocultas.
También debe anular tableView: numberOfRowsInSection: y devolver el número de filas en esa sección. Debe hacer algo extraño aquí para que si su tabla es un estilo agrupado, las esquinas redondeadas se produzcan en las celdas correctas. En mi tabla estática hay un conjunto completo de celdas para la sección, por lo que está la primera celda que contiene la opción, luego 1 celda para las opciones de estado ON y 2 celdas más para las opciones de estado OFF, un total de 4 celdas. Cuando la opción está activada, tengo que devolver 4, esto incluye la opción oculta para que la última opción mostrada tenga un cuadro redondeado. Cuando la opción está desactivada, las dos últimas opciones no se muestran, así que devuelvo 2. Todo esto se siente torpe. Lo siento si esto no está muy claro, es difícil de describir. Solo para ilustrar la configuración, esta es la construcción de la sección de tabla en IB:
Entonces, cuando la opción está activada, la tabla informa dos filas que son:
Cuando la opción está DESACTIVADA, la tabla informa cuatro filas que son:
Este enfoque no se siente correcto por varias razones, es tan lejos como he llegado hasta ahora con mi experimentación, así que avíseme si encuentra una mejor manera. Los problemas que he observado hasta ahora son:
Se siente mal decirle a la tabla que el número de filas es diferente de lo que presumiblemente está contenido en los datos subyacentes.
Parece que no puedo animar el cambio. Intenté usar tableView: reloadSections: withRowAnimation: en lugar de reloadData y los resultados no parecen tener sentido, todavía estoy tratando de que esto funcione. Actualmente, lo que parece suceder es que tableView no actualiza las filas correctas, por lo que permanece oculto y se debe mostrar un vacío debajo de la primera fila. Creo que esto podría estar relacionado con el primer punto sobre los datos subyacentes.
Esperemos que alguien pueda sugerir métodos alternativos o tal vez cómo ampliar con la animación, pero tal vez esto lo ayude a comenzar. Pido disculpas por la falta de hipervínculos a las funciones, las puse pero el filtro de spam las rechazó porque soy un usuario bastante nuevo.
fuente
[[self tableView] reloadData];
una vez más después de ocultar las celdasreturn [super tableView:tableView cellForRowAtIndexPath:indexPath];
a laUITableViewController
subclase para crear celdas estáticas. Las rutas de índice son estáticas indexadas, no dinámicas ...Según la respuesta de Justas, pero para Swift 4:
fuente
tableView.reloadRows(at:, with:)
para actualizar las celdas si cambia la altura mientras la fila ya está visible.Bien, después de intentarlo, tengo una respuesta no común. Estoy usando la variable "isHidden" u "hidden" para verificar si esta celda debe estar oculta.
cree un IBOutlet para su controlador de vista.
@IBOutlet weak var myCell: UITableViewCell!
Actualice el
myCell
en su función personalizada, por ejemplo, puede agregarlo en viewDidLoad:override func viewDidLoad() { super.viewDidLoad() self.myCell.isHidden = true }
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { let cell = super.tableView(tableView, cellForRowAt: indexPath) guard !cell.isHidden else { return 0 } return super.tableView(tableView, heightForRowAt: indexPath) }
Esto reducirá su lógica en el método de delegado, y solo necesita concentrarse en los requisitos de su negocio.
fuente
Las respuestas anteriores que ocultan / muestran celdas, cambian rowHeight o se meten con restricciones de diseño automático no me funcionaron debido a problemas de diseño automático. El código se volvió intolerable.
Para una tabla estática simple, lo que mejor funcionó para mí fue:
Aquí hay un ejemplo de mi controlador de vista de tabla:
fuente
Método simple compatible con iOS 11 e IB / Storyboard
Para iOS 11, descubrí que una versión modificada de la respuesta de Mohamed Saleh funcionó mejor, con algunas mejoras basadas en la documentación de Apple. Anima muy bien, evita cualquier truco feo o valores codificados, y utiliza alturas de fila ya establecidas en Interface Builder .
El concepto básico es establecer el alto de fila en 0 para cualquier fila oculta. Luego, use
tableView.performBatchUpdates
para activar una animación que funcione de manera consistente.Establecer las alturas de las celdas
Querrás asegurarte
cellIsHidden
yindexPathOfHiddenCell
estar configurado adecuadamente para tu caso de uso. Para mi código, son propiedades en mi controlador de vista de tabla.Alternar la celda
En cualquier método que controle la visibilidad (probablemente una acción de botón o
didSelectRow
), alterna el estado cellIsHidden, dentro de unperformBatchUpdates
bloque:Apple recomienda
performBatchUpdates
sobrebeginUpdates
/endUpdates
siempre que sea posible.fuente
Encontré una solución para animar las celdas ocultas en la tabla estática.
Solo se necesita un diccionario adicional:
Y observe la implementación de MyTableViewController. Necesitamos dos métodos para convertir indexPath entre índices visibles e invisibles ...
Un cambio de valor de IBAction en UISwitch:
Algunos métodos UITableViewDataSource y UITableViewDelegate:
fuente
Responda rápidamente :
Agregue el siguiente método en su TableViewController:
si tableView intenta dibujar la celda que desea ocultar, no la mostrará porque su altura se establecerá en 0pt gracias al método anterior, todo lo demás permanece inalterado.
Tenga en cuenta que
indexPathOfCellYouWantToHide
se puede cambiar en cualquier momento :)fuente
En> Swift 2.2, he combinado algunas respuestas aquí.
Haga una salida del guión gráfico para vincular a su staticCell.
Quiero ocultar mi primera celda, así que configuré la altura en 0 como se describió anteriormente.
fuente
Swift 4:
fuente
Para el escenario más fácil cuando oculta celdas en la parte inferior de la vista de tabla, puede ajustar el contenido de TableView después de ocultar la celda:
fuente
Esta es una nueva forma de hacer esto usando https://github.com/k06a/ABStaticTableViewController
fuente
La solución de k06a ( https://github.com/k06a/ABStaticTableViewController ) es mejor porque oculta toda la sección, incluidos los encabezados y pies de página de las celdas, donde esta solución ( https://github.com/peterpaulis/StaticDataTableViewController ) oculta todo excepto el pie de página.
EDITAR
Acabo de encontrar una solución si quieres ocultar el pie de página
StaticDataTableViewController
. Esto es lo que necesita copiar en el archivo StaticTableViewController.m:fuente
Seguramente puedes. Primero, regrese al número de celdas tableView que desea mostrar, luego llame
super
para lograr cierta celda de su guión gráfico y devuélvala para tableView:Si sus celdas tienen una altura diferente, devuélvala también:
fuente
Además de la solución @Saleh Masum:
Si obtiene errores de diseño automático , simplemente puede eliminar las restricciones del
tableViewCell.contentView
Swift 3:
Esta solución depende del flujo de su aplicación . Si desea mostrar / ocultar la celda en la misma instancia del controlador de vista, esta puede no ser la mejor opción, ya que elimina las restricciones .
fuente
Obtuve una mejor manera de ocultar celdas estáticas e incluso secciones dinámicamente sin ningún truco.
Establecer el alto de fila en 0 puede ocultar una fila, pero eso no funciona si desea ocultar una sección completa que contendrá algunos espacios incluso si oculta todas las filas.
Mi enfoque es construir una matriz de secciones de celdas estáticas. Luego, el contenido de la vista de tabla será controlado por la matriz de secciones.
Aquí hay un código de muestra:
De esta manera, puede armar todo su código de configuración sin tener que escribir el código desagradable para calcular el número de filas y secciones. Y por supuesto no
0
alturas.Este código también es muy fácil de mantener. Por ejemplo, si desea agregar / eliminar más celdas o secciones.
Del mismo modo, puede crear una matriz de título de encabezado de sección y una matriz de título de pie de página de sección para configurar sus títulos de sección dinámicamente.
fuente