ios objective-c uitableview ios7

ios - UITableView: la forma correcta de mostrar un separador para la última celda



objective-c ios7 (13)

Acabo de encontrar algo que funciona para mí. En pocas palabras: dele a su UITableView una tableFooterView y establezca la altura de su marco en 0 . Esto hace que se muestre un separador real, con las inserciones correctas.

En más detalles: si está utilizando el guión gráfico, arrastre UIView hasta la parte inferior de la vista de tabla (en la vista de árbol de la izquierda) para que se muestre justo debajo de la celda de vista de tabla, en el mismo nivel jerárquico. Esto crea un tableFooterView. Por supuesto, esto también puede hacerse mediante programación.

Luego, en la implementación de su UITableViewController:

UIView *footerView = self.tableView.tableFooterView; CGRect footerFrame = footerView.frame; footerFrame.size.height = 0; [footerView setFrame:footerFrame];

¡Hazme saber si eso funciona para ti! También podría funcionar para el primer separador si usa un TableHeaderView, pero aún no lo he probado.

La pregunta es cuál es la forma correcta de mostrar un separador en la última celda de una tabla / sección.

Básicamente esto es lo que estoy buscando.

Esto es de la aplicación de música nativa, lo que me hace pensar que debería ser posible lograrlo solo mediante UITableView , ellos no estarían usando una API privada para separadores de celdas, ¿verdad?

Sé que puedes escapar sin usar separadores reales, pero si agregas una línea de píxeles en la parte inferior de la celda. Pero no soy fan de este enfoque porque

  1. Cuando se selecciona / resalta una celda, su separador y el separador de la celda anterior se ocultan automáticamente (ver la segunda captura de pantalla con "Tienes que estar loco" seleccionado). Y esto es algo que quiero que UITableView maneje en lugar de hacerlo yo mismo si uso una línea de un píxel (que es especialmente útil cuando los separadores de celdas no se extienden hasta el borde de la vista de tabla, los separadores y el fondo de celda seleccionado no se ven bien juntos).
  2. Me gustaría mantener mis células lo más planas posible para el rendimiento de desplazamiento.

También hay algo en la referencia de UITableView que me hace pensar que hay una manera fácil de obtener lo que quiero:

En iOS 7 y posterior, los separadores de celdas no se extienden hasta el borde de la vista de tabla. Esta propiedad establece el recuadro predeterminado para todas las celdas de la tabla, al igual que rowHeight establece la altura predeterminada para las celdas. También se usa para gestionar los separadores "extra" dibujados en la parte inferior de las tablas de estilo simple.

¿Alguien sabe exactamente cómo usar estos separadores "extra" dibujados en la parte inferior de las tablas de estilo simple? Porque esto es exactamente lo que necesito. Pensé que asignar separatorInset a UITableView , no UITableViewCell haría el truco, pero no es así, la última celda aún no tiene su separador.

En este momento solo veo una opción: tener un pie de página personalizado para imitar el separador de la última celda. Y esto no es bueno, especialmente si desea tener un pie de página de sección real utilizando el tableView:titleForFooterInSection: .


Así que aquí hay una solución súper simple en Swift 4 que funciona:

Dentro de override func viewDidLoad(){} , simplemente implementé esta línea de código:

self.tableView.tableFooterView = UIView(frame: .zero)

Por lo tanto, asegura que solo la última celda obtiene el inserto del separador.

Esto funcionó perfectamente para mí, ¡espero que también lo haga para ti!


Cuando agrega headerView o footerView a su TableView, la última línea de separación desaparecerá.

El siguiente ejemplo le permitirá realizar una solución para mostrar el separador en la última celda. Lo único que tiene que implementar más es hacer desaparecer este separador después de seleccionar celda, por lo que el comportamiento es el mismo que en el resto de las celdas.

Para Swift 4.0

func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { let result = UIView() // recreate insets from existing ones in the table view let insets = tableView.separatorInset let width = tableView.bounds.width - insets.left - insets.right let sepFrame = CGRect(x: insets.left, y: -0.5, width: width, height: 0.5) // create layer with separator, setting color let sep = CALayer() sep.frame = sepFrame sep.backgroundColor = tableView.separatorColor?.cgColor result.layer.addSublayer(sep) return result }


El siguiente código funcionó para mí:

UIView *footerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 0.35)]; footerView.backgroundColor = [UIColor whiteColor]; CGRect frame = footerView.frame; frame.origin.x = 15; frame.size.width = frame.size.width - 15; UIView *blackView = [[UIView alloc] initWithFrame:frame]; [blackView setBackgroundColor:[UIColor blackColor]]; blackView.alpha = 0.25; [footerView addSubview:blackView]; tableView.tableFooterView = footerView;

Espero que funcione para usted también.


En iOS 8, si tiene un estilo simple UITableView, y agrega un pie de página, el último separador se ha ido. Sin embargo, puede recrearlo fácilmente agregando una vista de separador personalizada al pie de página.

Este ejemplo imita exactamente el estilo Today Widget separator

override func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { //create footer view let result = UIView() result.frame.size.height = tableView.rowHeight //recreate last cell separator, which gets hidden by footer let sepFrame = CGRectMake(15, -0.5, tableView.frame.width, 0.5); let vibrancyEffectView = UIVisualEffectView.init(effect: UIVibrancyEffect.notificationCenterVibrancyEffect()) vibrancyEffectView.frame = sepFrame vibrancyEffectView.contentView.backgroundColor = tableView.separatorColor result.addSubview(vibrancyEffectView) return result }


Esto es definitivamente ayuda. Trabajando. pero configure el separador "ninguno" del inspector de atributos. Escriba el siguiente código en el método cellForRowAtIndexPath

if(indexPath.row==arrData.count-1){ UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0, cell.contentView.frame.size.height - 1.0, cell.contentView.frame.size.width, 1)]; lineView.backgroundColor = [UIColor blackColor]; [cell.contentView addSubview:lineView]; }


Esto funcionó perfectamente para agregar un separador a la última celda. ¡que te diviertas!

self.tableView.tableFooterView = [[UIView alloc] init];


Funciona en iOS 7.xy 8.x (póngalo en cellForRowAtIndexPath):

(PS sustituye "elementos máximos de su fuente de datos" con el recuento de fuente de datos de la matriz)

if (row == <max elements of your datasource>-1) { UIView* separatorLineView = [[UIView alloc] initWithFrame:CGRectMake(0, cell.contentView.frame.size.height-1, self.view.frame.size.width, 1)];/// change size as you need. separatorLineView.tag = 666; separatorLineView.backgroundColor = [UIColor colorWithRed: 204.0/255.0 green: 204.0/255.0 blue: 204.0/255.0 alpha:1.0]; UIView *separator = [cell.contentView viewWithTag:666]; // case of orientation changed.. if (separator.frame.size.width != cell.contentView.frame.size.width) { [[cell.contentView viewWithTag:666] removeFromSuperview]; separator = nil; } if (separator==nil) [cell.contentView addSubview:separatorLineView]; }


Puedes hacer algo como esto si no estás usando secciones:

- (void)viewDidLoad { self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(insetLeftSide, 0, width - insetRightSide, 1)]; }

Si está utilizando secciones, implemente el pie de página en cada sección como una vista de un punto en los métodos

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section { } - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { }

Esto le permitirá tener un separador para su última celda que, de hecho, no es un separador, es un pie de página con el que puede jugar y hacer que parezca un separador


Si agrega un pie de página vacío, la vista de tabla eliminará todos los separadores de líneas restantes (para las celdas que no existen) pero incluirá el separador de la última celda:

- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section { return [UIView new]; }


Tuve un problema similar y encontré una solución alternativa. Apple oculta el último separador uitableviewcell y luego lo muestra si selecciona la celda o si llama seleccione y deseleccione en esa celda.

Así que enseñé que lo mejor está en - (void)layoutSubviews . La vista de separador se llama _separatorView y es una propiedad privada. Usando los estados seleccionados / resaltados de la celda, puedes encontrar algo como esto:

- (void)layoutSubviews { // Call super so the OS can do it''s layout first [super layoutSubviews]; // Get the separator view UIView *separatorView = [self valueForKey:@"_separatorView"]; // Make the custom inset CGRect newFrame = CGRectMake(0.0, 0.0, self.bounds.size.width, separatorView.frame.size.height); newFrame = CGRectInset(newFrame, 15.0, 0.0); [separatorView setFrame:newFrame]; // Show or hide the bar based on cell state if (!self.selected) { separatorView.hidden = NO; } if (self.isHighlighted) { separatorView.hidden = YES; } }

Algo como esto.


esto hará exactamente lo que quieras ... aunque la línea ocupará todo el ancho de la celda:

en - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

self.tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; self.tableView.separatorColor = [UIColor redColor]; self.tableView.separatorInset = UIEdgeInsetsZero;


Swift 3

Encontré este viejo problema, así que intenté lo mismo en Swift:

tableView.tableFooterView = UIView() tableView.tableFooterView?.height = 0 // Maybe not necessary

Pero conduce a otro problema (en mi caso). Así que lo resolví de manera diferente. Agregué una celda extra al final de esta sección, vacía y con una altura igual a cero:

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return previousNumberOfRows + 1 } override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return indexPath.row == previousNumberOfRows ? 0 : previousCellHeight } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { if indexPath.row == items.count { return UITableViewCell() } else { previousCellInitialization() }

Esta es una solución menos concisa, pero funciona en más casos, si tiene varias secciones, vistas de pie de página existentes ...