Ocultar línea de separación en una UITableViewCell

Estoy personalizando una UITableView . Quiero ocultar la línea que se separa en la última celda … ¿puedo hacer esto?

Sé que puedo hacer tableView.separatorStyle = UITableViewCellStyle.None pero eso afectaría todas las celdas de tableView. Quiero que solo afecte mi última celda.

en viewDidLoad , agregue esta línea:

 self.tableView.separatorColor = [UIColor clearColor]; 

y en cellForRowAtIndexPath :

para versiones inferiores de iOS

 if(indexPath.row != self.newCarArray.count-1){ UIImageView *line = [[UIImageView alloc] initWithFrame:CGRectMake(0, 44, 320, 2)]; line.backgroundColor = [UIColor redColor]; [cell addSubview:line]; } 

para iOS 7 versiones superiores (incluido iOS 8)

 if (indexPath.row == self.newCarArray.count-1) { cell.separatorInset = UIEdgeInsetsMake(0.f, cell.bounds.size.width, 0.f, 0.f); } 

Puedes usar el siguiente código:

Swift:

 if indexPath.row == {your row number} { cell.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: .greatestFiniteMagnitude) } 

o:

 cell.separatorInset = UIEdgeInsetsMake(0, 0, 0, UIScreen.main.bounds.width) 

para el Margen predeterminado:

 cell.separatorInset = UIEdgeInsetsMake(0, tCell.layoutMargins.left, 0, 0) 

mostrar el separador de extremo a extremo

 cell.separatorInset = .zero 

C objective:

 if (indexPath.row == {your row number}) { cell.separatorInset = UIEdgeInsetsMake(0.0f, 0.0f, 0.0f, CGFLOAT_MAX); } 

Para dar seguimiento a la respuesta de Hiren .

en ViewDidLoad y en la siguiente línea:

 self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; 

O, si está utilizando XIB o Storyboards, cambie ” separador ” a ” ninguno “:

Constructor de interfaz

Y en CellForRowAtIndexPath agrega esto:

 CGFloat separatorInset; // Separator x position CGFloat separatorHeight; CGFloat separatorWidth; CGFloat separatorY; UIImageView *separator; UIColor *separatorBGColor; separatorY = cell.frame.size.height; separatorHeight = (1.0 / [UIScreen mainScreen].scale); // This assures you to have a 1px line height whatever the screen resolution separatorWidth = cell.frame.size.width; separatorInset = 15.0f; separatorBGColor = [UIColor colorWithRed: 204.0/255.0 green: 204.0/255.0 blue: 204.0/255.0 alpha:1.0]; separator = [[UIImageView alloc] initWithFrame:CGRectMake(separatorInset, separatorY, separatorWidth,separatorHeight)]; separator.backgroundColor = separatorBGColor; [cell addSubView: separator]; 

Aquí hay un ejemplo del resultado donde visualizo una vista de tabla con celdas dinámicas (pero solo tengo una sola con contenido). El resultado es que solo ese tiene un separador y no todos los “ficticios”, la vista de tabla se agrega automáticamente para llenar la pantalla.

enter image description here

Espero que esto ayude.

EDITAR: para aquellos que no siempre leen los comentarios, en realidad hay una mejor manera de hacerlo con unas pocas líneas de código:

 override func viewDidLoad() { super.viewDidLoad() tableView.tableFooterView = UIView() } 

Si no desea dibujar el separador usted mismo, use esto:

  // Hide the cell separator by moving it to the far right cell.separatorInset = UIEdgeInsetsMake(0, 10000, 0, 0); 

Esta API solo está disponible a partir de iOS 7.

mi entorno de desarrollo es

  • Xcode 7.0
  • 7A220 Swift 2.0
  • iOS 9.0

las respuestas anteriores no funcionan completamente para mí

después de probar, mi solución finalmente funcional es:

 let indent_large_enought_to_hidden:CGFloat = 10000 cell.separatorInset = UIEdgeInsetsMake(0, indent_large_enought_to_hidden, 0, 0) // indent large engough for separator(including cell' content) to hidden separator cell.indentationWidth = indent_large_enought_to_hidden * -1 // adjust the cell's content to show normally cell.indentationLevel = 1 // must add this, otherwise default is 0, now actual indentation = indentationWidth * indentationLevel = 10000 * 1 = -10000 

y el efecto es: enter image description here

Mejor solución para iOS 7 y 8

 -(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { DLog(@""); if (cell && indexPath.row == 0 && indexPath.section == 0) { DLog(@"cell.bounds.size.width %f", cell.bounds.size.width); cell.separatorInset = UIEdgeInsetsMake(0.f, cell.bounds.size.width, 0.f, 0.0f); } } 

Si su aplicación es rotativa, use 3000.0f para la constante del recuadro izquierdo o calcúlela sobre la marcha. Si intenta establecer el recuadro derecho, tiene una parte visible del separador en el lado izquierdo de la celda en iOS 8.

En iOS 7, el separador de celdas de estilo agrupado de UITableView se ve un poco diferente. Se parece un poco a esto:

enter image description here

Intenté la respuesta de Kemenaran de hacer esto:

 cell.separatorInset = UIEdgeInsetsMake(0, 10000, 0, 0); 

Sin embargo, eso no parece funcionar para mí. No estoy seguro por qué. Así que decidí usar la respuesta de Hiren, pero usando UIView lugar de UIImageView , y UIImageView la línea en el estilo de iOS 7:

 UIColor iOS7LineColor = [UIColor colorWithRed:0.82f green:0.82f blue:0.82f alpha:1.0f]; //First cell in a section if (indexPath.row == 0) { UIView *line = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 1)]; line.backgroundColor = iOS7LineColor; [cell addSubview:line]; [cell bringSubviewToFront:line]; } else if (indexPath.row == [self.tableViewCellSubtitles count] - 1) { UIView *line = [[UIView alloc] initWithFrame:CGRectMake(21, 0, self.view.frame.size.width, 1)]; line.backgroundColor = iOS7LineColor; [cell addSubview:line]; [cell bringSubviewToFront:line]; UIView *lineBottom = [[UIView alloc] initWithFrame:CGRectMake(0, 43, self.view.frame.size.width, 1)]; lineBottom.backgroundColor = iOS7LineColor; [cell addSubview:lineBottom]; [cell bringSubviewToFront:lineBottom]; } else { //Last cell in the table view UIView *line = [[UIView alloc] initWithFrame:CGRectMake(21, 0, self.view.frame.size.width, 1)]; line.backgroundColor = iOS7LineColor; [cell addSubview:line]; [cell bringSubviewToFront:line]; } 

Si usa esto, asegúrese de conectar la altura correcta de la vista de tabla en la segunda statement if. Espero que esto sea útil para alguien.

En Swift 3 y Swift 4 , puede escribir una extensión a UITableViewCell así:

 extension UITableViewCell { func hideSeparator() { self.separatorInset = UIEdgeInsets(top: 0, left: self.bounds.size.width, bottom: 0, right: 0) } func showSeparator() { self.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) } } 

Entonces puede usar esto como a continuación (cuando cell es su instancia de celda):

 cell.hideSeparator() cell.showSeparator() 

En realidad, es mejor asignar el ancho de la celda de la vista de tabla como recuadro izquierdo en lugar de asignarle un número aleatorio. Debido a que en algunas dimensiones de pantalla, tal vez no ahora, pero en el futuro sus separadores aún pueden ser visibles porque ese número aleatorio puede no ser suficiente. Además, en iPad en modo horizontal, no puedes garantizar que tus separadores siempre serán invisibles.

En Swift usando iOS 8.4 :

 /* Tells the delegate that the table view is about to draw a cell for a particular row. (optional) */ override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { if indexPath.row == 3 { // Hiding separator line for only one specific UITableViewCell cell.separatorInset = UIEdgeInsetsMake(0, cell.bounds.size.width, 0, 0) } } 

Nota: este fragmento de arriba funcionará en UITableView usando celdas dinámicas. El único problema que puede encontrar es cuando utiliza celdas estáticas con categorías, un tipo de separador diferente de ninguno y un estilo agrupado para la vista de tabla. De hecho, en este caso particular, no ocultará la última celda de cada categoría. Para superar eso, la solución que encontré fue establecer el separador de células (a través de IB) en ninguno y luego crear y agregar manualmente (a través del código) la vista de línea a cada celda. Para un ejemplo, verifique el siguiente fragmento:

 /* Tells the delegate that the table view is about to draw a cell for a particular row. (optional) */ override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { // Row 2 at Section 2 if indexPath.row == 1 && indexPath.section == 1 { // Hiding separator line for one specific UITableViewCell cell.separatorInset = UIEdgeInsetsMake(0, cell.bounds.size.width, 0, 0) // Here we add a line at the bottom of the cell (eg here at the second row of the second section). let additionalSeparatorThickness = CGFloat(1) let additionalSeparator = UIView(frame: CGRectMake(0, cell.frame.size.height - additionalSeparatorThickness, cell.frame.size.width, additionalSeparatorThickness)) additionalSeparator.backgroundColor = UIColor.redColor() cell.addSubview(additionalSeparator) } } 

Use esta subclase, configure separatorInset no funciona para iOS 9.2.1, el contenido sería comprimido.

 @interface NSPZeroMarginCell : UITableViewCell @property (nonatomic, assign) BOOL separatorHidden; @end @implementation NSPZeroMarginCell - (void) layoutSubviews { [super layoutSubviews]; for (UIView *view in self.subviews) { if (![view isKindOfClass:[UIControl class]]) { if (CGRectGetHeight(view.frame) < 3) { view.hidden = self.separatorHidden; } } } } @end 

https://gist.github.com/liruqi/9a5add4669e8d9cd3ee9

No creo que este enfoque funcione bajo ninguna circunstancia con células dinámicas …

 if (indexPath.row == self.newCarArray.count-1) { cell.separatorInset = UIEdgeInsetsMake(0.f, cell.bounds.size.width, 0.f, 0.f); } 

No importa en qué método de vista de tabla lo haga en celdas dinámicas, la celda en la que ha cambiado la propiedad de inserción siempre tendrá la propiedad de inserción establecida cada vez que se quita la cola, causando una avalancha de separadores de línea faltantes … Eso es hasta que cámbialo tú mismo.

Algo como esto funcionó para mí:

 if indexPath.row == franchises.count - 1 { cell.separatorInset = UIEdgeInsetsMake(0, cell.contentView.bounds.width, 0, 0) } else { cell.separatorInset = UIEdgeInsetsMake(0, 0, cell.contentView.bounds.width, 0) } 

De esta forma, actualizas tu estado de estructura de datos en cada carga

En su subclase UITableViewCell, anule el diseño de las presentaciones y oculte el _UITableViewCellSeparatorView. Funciona bajo iOS 10.

 override func layoutSubviews() { super.layoutSubviews() subviews.forEach { (view) in if view.dynamicType.description() == "_UITableViewCellSeparatorView" { view.hidden = true } } } 
  if([_data count] == 0 ){ [self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];// [self tableView].=YES; } else { [self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleSingleLine];//// [self tableView].hidden=NO; } 

En willdisplaycell :

 cell.separatorInset = UIEdgeInsetsMake(0, cell.bounds.size.width, 0, 0) 

si la respuesta aceptada no funciona, puede intentar esto:

 - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { return 0.01f; } 

Es genial 😉

Rápido:

 public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { ... // remove separator for last cell cell.separatorInset = indexPath.row < numberOfRowsInSection-1 ? tableView.separatorInset : UIEdgeInsets(top: 0, left: tableView.bounds.size.width, bottom: 0, right: 0) return cell } 

C objective:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { ... // remove separator for last cell cell.separatorInset = (indexPath.row < numberOfRowsInSection-1) ? tableView.separatorInset : UIEdgeInsetsMake(0.f, tableView.bounds.size.width, 0.f, 0.f); return cell; } 

Usando Swift 3 y adoptando el método de hacking más rápido, puedes mejorar el código usando extensiones :

 extension UITableViewCell { var isSeparatorHidden: Bool { get { return self.separatorInset.right != 0 } set { if newValue { self.separatorInset = UIEdgeInsetsMake(0, self.bounds.size.width, 0, 0) } else { self.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0) } } } } 

Luego, cuando configuras la celda:

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "identifier", for: indexPath) switch indexPath.row { case 3: cell.isSeparatorHidden = true default: cell.isSeparatorHidden = false } return cell } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let cell = tableView.cellForRow(at: indexPath) if cell.isSeparatorHidden { // do stuff } } 

Pruebe el siguiente código, puede ayudarlo a resolver su problema

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSString* reuseIdentifier = @"Contact Cell"; UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier]; if (nil == cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier]; if (indexPath.row != 10) {//Specify the cell number cell.backgroundView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"bgWithLine.png"]]; } else { cell.backgroundView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"bgWithOutLine.png"]]; } } return cell; } 
 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSString *cellId = @"cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId]; NSInteger lastRowIndexInSection = [tableView numberOfRowsInSection:indexPath.section] - 1; if (row == lastRowIndexInSection) { CGFloat halfWidthOfCell = cell.frame.size.width / 2; cell.separatorInset = UIEdgeInsetsMake(0, halfWidthOfCell, 0, halfWidthOfCell); } } 

Debe tomar una celda personalizada y agregar Etiqueta y establecer restricciones, como la etiqueta debe cubrir el área de la celda completa. y escribe la siguiente línea en constructor.

 - (void)awakeFromNib { // Initialization code self.separatorInset = UIEdgeInsetsMake(0, 10000, 0, 0); //self.layoutMargins = UIEdgeInsetsZero; [self setBackgroundColor:[UIColor clearColor]]; [self setSelectionStyle:UITableViewCellSelectionStyleNone]; } 

También configure el margen de Layout de UITableView de la siguiente manera

 tblSignup.layoutMargins = UIEdgeInsetsZero; 

La mejor forma de lograr esto es desactivar los separadores de línea predeterminados, la subclase UITableViewCell y agregar un separador de línea personalizado como subvista de contentView ; consulte a continuación una celda personalizada que se usa para presentar un objeto del tipo SNStock que tiene dos propiedades de cadena, ticker y name :

 import UIKit private let kSNStockCellCellHeight: CGFloat = 65.0 private let kSNStockCellCellLineSeparatorHorizontalPaddingRatio: CGFloat = 0.03 private let kSNStockCellCellLineSeparatorBackgroundColorAlpha: CGFloat = 0.3 private let kSNStockCellCellLineSeparatorHeight: CGFloat = 1 class SNStockCell: UITableViewCell { private let primaryTextColor: UIColor private let secondaryTextColor: UIColor private let customLineSeparatorView: UIView var showsCustomLineSeparator: Bool { get { return !customLineSeparatorView.hidden } set(showsCustomLineSeparator) { customLineSeparatorView.hidden = !showsCustomLineSeparator } } var customLineSeparatorColor: UIColor? { get { return customLineSeparatorView.backgroundColor } set(customLineSeparatorColor) { customLineSeparatorView.backgroundColor = customLineSeparatorColor?.colorWithAlphaComponent(kSNStockCellCellLineSeparatorBackgroundColorAlpha) } } required init(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } init(reuseIdentifier: String, primaryTextColor: UIColor, secondaryTextColor: UIColor) { self.primaryTextColor = primaryTextColor self.secondaryTextColor = secondaryTextColor self.customLineSeparatorView = UIView(frame:CGRectZero) super.init(style: UITableViewCellStyle.Subtitle, reuseIdentifier:reuseIdentifier) selectionStyle = UITableViewCellSelectionStyle.None backgroundColor = UIColor.clearColor() contentView.addSubview(customLineSeparatorView) customLineSeparatorView.hidden = true } override func prepareForReuse() { super.prepareForReuse() self.showsCustomLineSeparator = false } // MARK: Layout override func layoutSubviews() { super.layoutSubviews() layoutCustomLineSeparator() } private func layoutCustomLineSeparator() { let horizontalPadding: CGFloat = bounds.width * kSNStockCellCellLineSeparatorHorizontalPaddingRatio let lineSeparatorWidth: CGFloat = bounds.width - horizontalPadding * 2; customLineSeparatorView.frame = CGRectMake(horizontalPadding, kSNStockCellCellHeight - kSNStockCellCellLineSeparatorHeight, lineSeparatorWidth, kSNStockCellCellLineSeparatorHeight) } // MARK: Public Class API class func cellHeight() -> CGFloat { return kSNStockCellCellHeight } // MARK: Public API func configureWithStock(stock: SNStock) { textLabel!.text = stock.ticker as String textLabel!.textColor = primaryTextColor detailTextLabel!.text = stock.name as String detailTextLabel!.textColor = secondaryTextColor setNeedsLayout() } } 

Para deshabilitar el uso del separador de línea predeterminado, tableView.separatorStyle = UITableViewCellSeparatorStyle.None; . El lado del consumidor es relativamente simple, vea el ejemplo a continuación:

 private func stockCell(tableView: UITableView, indexPath:NSIndexPath) -> UITableViewCell { var cell : SNStockCell? = tableView.dequeueReusableCellWithIdentifier(stockCellReuseIdentifier) as? SNStockCell if (cell == nil) { cell = SNStockCell(reuseIdentifier:stockCellReuseIdentifier, primaryTextColor:primaryTextColor, secondaryTextColor:secondaryTextColor) } cell!.configureWithStock(stockAtIndexPath(indexPath)) cell!.showsCustomLineSeparator = true cell!.customLineSeparatorColor = tintColor return cell! } 

No pude ocultar el separador en una celda específica, excepto con la siguiente solución

 - (void)layoutSubviews { [super layoutSubviews]; [self hideCellSeparator]; } // workaround - (void)hideCellSeparator { for (UIView *view in self.subviews) { if (![view isKindOfClass:[UIControl class]]) { [view removeFromSuperview]; } } } 

Para Swift 2:

agregue la siguiente línea a viewDidLoad() :

 tableView.separatorColor = UIColor.clearColor() 

Para iOS7 y superior, la manera más limpia es utilizar INFINITY en lugar de valor codificado. No tiene que preocuparse por actualizar la celda cuando la pantalla gira.

 if (indexPath.row == ) { cell.separatorInset = UIEdgeInsetsMake(0, INFINITY, 0, 0); } 

Mi requisito era ocultar el separador entre la 4ta y la 5ta celda. Lo logré por

  -(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { if(indexPath.row == 3) { cell.separatorInset = UIEdgeInsetsMake(0, cell.bounds.size.width, 0, 0); } } 
 cell.separatorInset = UIEdgeInsetsMake(0.0, cell.bounds.size.width, 0.0, -cell.bounds.size.width) 

funciona bien en iOS 10.2

enter image description here

Lo mucho más simple y lógico es hacer esto:

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

En la mayoría de los casos, no desea ver solo el último separador tableCiewCell. Y este enfoque elimina solo el último separador tableViewCell, y no necesita pensar en problemas de autolayout (es decir, dispositivo giratorio) o valores de código rígido para configurar separaciones de separador.

Como (muchos) otros han señalado, puede ocultar fácilmente todos los separadores UITableViewCell simplemente apagándolos para todo el UITableView mismo; por ejemplo, en su UITableViewController

 - (void)viewDidLoad { ... self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; ... } 

Desafortunadamente, es un PITA real para hacer por celda , que es lo que realmente estás preguntando.

Personalmente, he probado numerosas permutaciones para cambiar cell.separatorInset.left , una vez más, como (muchos) otros han sugerido, pero el problema es, para citar a Apple (énfasis añadido):

… Puede usar esta propiedad para agregar espacio entre el contenido de la celda actual y los bordes izquierdo y derecho de la tabla. Los valores de inserción positivos mueven el contenido de la celda y el separador de celdas hacia adentro y lejos de los bordes de la tabla …

Por lo tanto, si intenta ‘ocultar’ el separador al desplazarlo fuera de la pantalla hacia la derecha, también puede terminar hilvanando el contenido de su celda. Como sugiere crifan, puedes intentar compensar este desagradable efecto secundario configurando cell.indentationWidth y cell.indentationLevel apropiada para mover todo de vuelta, pero he encontrado que esto también es poco confiable (el contenido sigue sangrando … )

La manera más confiable que he encontrado es layoutSubviews en una subclase UITableViewCell simple y establecer el recuadro derecho para que toque el recuadro izquierdo, haciendo que el separador tenga un ancho de 0 e invisible [esto debe hacerse en layoutSubviews to manejar automáticamente las rotaciones]. También agregué un método de conveniencia a mi subclase para activar esto.

 @interface MyTableViewCellSubclass() @property BOOL separatorIsHidden; @end @implementation MyTableViewCellSubclass - (void)hideSeparator { _separatorIsHidden = YES; } - (void)layoutSubviews { [super layoutSubviews]; if (_separatorIsHidden) { UIEdgeInsets inset = self.separatorInset; inset.right = self.bounds.size.width - inset.left; self.separatorInset = inset; } } @end 

Advertencia: no hay una forma confiable de restablecer el recuadro derecho original , por lo que no puede “ocultar” el separador, por lo tanto, estoy utilizando un método hideSeparator irreversible (frente a la exposición de separatorIsHidden). Tenga en cuenta que el separatorInset persiste en las celdas reutilizadas, por lo que, debido a que no puede “ocultarlo”, debe mantener estas celdas separadas y separadas en su propio reuseIdentifier.

En iOS9 tuve el problema de que el cambio de las inserciones del separador también afecta el posicionamiento de las tags de texto y detalles.

Lo resolví con esto

 override func layoutSubviews() { super.layoutSubviews() separatorInset = UIEdgeInsets(top: 0, left: layoutMargins.left, bottom: 0, right: width - layoutMargins.left) } 

Funciona para mí cuando uso la extensión y llamo dentro de layoutSubviews () para las vistas de diseño de actualización de inmediato.

 extension UITableViewCell { func removeSeparator() { separatorInset = UIEdgeInsetsMake(0, bounds.size.width, 0, 0) } } override func layoutSubviews() { super.layoutSubviews() removeSeparator() }