ios - reproduccion - Oculte celdas en un UITableView con celdas estáticas, y no se producirá un bloqueo de reproducción automática
chrome://flags/#autoplay-policy (9)
Tengo un formulario de vista de tabla creado utilizando células estáticas en IB / Storyboard. Sin embargo, necesito ocultar algunas de las celdas en tiempo de ejecución dependiendo de ciertas condiciones.
He encontrado algunas respuestas; a esta pregunta en SO, por ejemplo
UITableView establecido en celdas estáticas. ¿Es posible ocultar algunas de las celdas programáticamente?
.. y se enfocan en establecer la altura de la celda / fila en 0. Esto es genial, excepto que ahora obtengo excepciones de AutoLayout porque las restricciones no pueden cumplirse. ¿Cómo puedo solucionar este último problema? ¿Puedo deshabilitar temporalmente el diseño automático para una subvista? ¿Hay una mejor manera de hacerlo en iOS7?
Descubrí que la mejor manera de hacer esto es simplemente manejar numberOfRowsInSection, cellForRowAtIndexPath y heightForRowAtIndexPath para eliminar ciertas filas de forma selectiva. Aquí hay un ejemplo ''codificado'' para mi escenario, usted podría hacer algo un poco más inteligente para eliminar de manera inteligente ciertas celdas en lugar de codificarlo de esta manera, pero esto fue lo más fácil para mi escenario simple.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
if (indexPath.section == 0 && hideStuff) {
cell = self.cellIWantToShow;
}
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGFloat height = [super tableView:tableView heightForRowAtIndexPath:indexPath];
if (indexPath.section == 0 && hideStuff) {
height = [super tableView:tableView heightForRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:0]];
}
return height;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger count = [super tableView:tableView numberOfRowsInSection:section];
if (section == 0 && hideStuff) {
count -= hiddenCells.count;
}
return count;
}
He encontrado una manera que le permite incluso animaciones de fila y está trabajando en iOS 8.3. Todo lo que necesita es implementar el método de fuente de datos tableView: numberOfRowsInSection: y luego agregar / eliminar la fila mediante los métodos UITableView insertRowsAtIndexPaths: withRowAnimation: y deleteRowsAtIndexPaths: withRowAnimation:.
Aquí hay un ejemplo de cómo ocultar la fila exacta según el estado de UISwitch :
- (IBAction)alowNotif:(id)sender {
UISwitch *sw = (UISwitch*)sender;
NSIndexPath *index = [NSIndexPath indexPathForRow:5 inSection:0];
if ([sw isOn]) {
[self.tableView insertRowsAtIndexPaths:@[index] withRowAnimation:UITableViewRowAnimationAutomatic];
}
else {
[self.tableView deleteRowsAtIndexPaths:@[index] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (![notifications isOn]) {
return 5;
}
return 6;
}
Como se mencionó anteriormente en @algal, numberOfRowInSection: sigue siendo el método UITableViewDataSource , por lo que uno no simplemente sabe cuánto tiempo funcionará.
Implementado esto también, para una vista de tabla en un StoryBoard. Mis celdas están incrustadas en secciones con un encabezado, representado por ese cubo azul en xcode6 IB. De hecho, si implementa heightForHeaderInSection, heightForFooterInSection y titleForHeaderInSection, titleForFooterInSection puede acceder a los encabezados cuando se muestra la tabla y devolver 0.0 y nil respectivamente, y devolver 0 para numberOfRowsInSection.
Básicamente, todo funciona bien, excepto que por cada celda oculta un ca. Se mantiene un espacio vertical de 10 píxeles de alto para cada celda (sección) que oculte. ¿Alguna idea de lo que podría ser?
La forma kosher de hacer esto es usar celdas dinámicas, estableciendo la altura de la fila en 0 es un hack. Las celdas estáticas son muy convenientes pero limitadas en funcionalidad.
La forma más sencilla es cambiar la altura de las secciones y filas. Esto funciona para mi.
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
if (section == 3) {
return 0;
} else {
return [super tableView:tableView heightForHeaderInSection:section];
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
if (indexPath.section == 3) {
cell.hidden = YES;
return 0;
} else {
cell.hidden = NO;
return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}
}
La mejor manera para mí fue modificar el método numberOfRowsInSection. Quité la fuente de datos que no quería mostrar. La mejor solución para mí, porque todo está en una función.
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if(section==0) {
NSUInteger productCount = _products.count;
for(loop trough your data) {
if(your condition is true)
productCount--;
}
}
return productCount;
} else
return self.groups.count;
}
Oculta las celdas en el guión gráfico y establece la altura en 0:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
let cell: UITableViewCell = super.tableView(tableView, cellForRowAtIndexPath:indexPath)
return cell.hidden ? 0 : super.tableView(tableView, heightForRowAtIndexPath:indexPath)
}
}
Si se asegura de que no haya ninguna restricción al tocar el borde inferior de la celda, el autolayout no debería barf (probado en iOS 6.0, 6.1, 7.0). Seguirás ''anclando'' al borde superior y tendrás que fijar las alturas. (Puede hacer lo contrario y anclar a la parte inferior, por supuesto).
Si su diseño depende de las posiciones del borde superior e inferior, puede ser posible eliminar las restricciones mediante programación (después de todo, solo son objetos).
contentView
evitar las excepciones del diseño automático eliminando primero las restricciones en contentView
la celda contentView
programación en viewDidLoad
, y luego configurando la altura de esa celda en 0 en heightForRowAtIndexPath
.