uitableviewcell tutorial ejemplo customize iphone ios uitableview

iphone - tutorial - La subvista UITableViewCell desaparece cuando se selecciona la celda



uitableview ios (19)

Estoy implementando una vista de tabla de selección de color en la que el usuario puede seleccionar entre, por ejemplo, 10 colores (depende del producto). El usuario también puede seleccionar otras opciones (como la capacidad del disco duro, ...).

Todas las opciones de color están dentro de su propia sección de vista de tabla.

Quiero mostrar un pequeño cuadrado a la izquierda de la etiqueta de texto que muestra el color real.

Ahora estoy agregando un UIView cuadrado simple, le doy el color de fondo correcto, así:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:RMProductAttributesCellID]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:RMProductAttributesCellID] autorelease]; cell.indentationWidth = 44 - 8; UIView *colorThumb = [[[UIView alloc] initWithFrame:CGRectMake(8, 8, 28, 28)] autorelease]; colorThumb.tag = RMProductAttributesCellColorThumbTag; colorThumb.hidden = YES; [cell.contentView addSubview:colorThumb]; } RMProductAttribute *attr = (RMProductAttribute *)[_product.attributes objectAtIndex:indexPath.section]; RMProductAttributeValue *value = (RMProductAttributeValue *)[attr.values objectAtIndex:indexPath.row]; cell.textLabel.text = value.name; cell.textLabel.backgroundColor = [UIColor clearColor]; UIView *colorThumb = [cell viewWithTag:RMProductAttributesCellColorThumbTag]; colorThumb.hidden = !attr.isColor; cell.indentationLevel = (attr.isColor ? 1 : 0); if (attr.isColor) { colorThumb.layer.cornerRadius = 6.0; colorThumb.backgroundColor = value.color; } [self updateCell:cell atIndexPath:indexPath]; return cell; }

Esto se muestra bien sin problemas.

Mi único problema es que cuando selecciono una fila de "color", durante la animación de selección de fundido a azul, mi UIView personalizada (colorThumb) está oculta. Se vuelve a visualizar justo después de que finalizó la animación de selección / cancelación, pero esto produce un artefacto feo.

¿Qué debo hacer para corregir esto? ¿No inserto la subvista en el lugar correcto?

(No hay nada especial en didSelectRowAtIndexPath, simplemente cambio el accesorio de la celda a una casilla de verificación o nada, y deselecciono el actual indexPath).


Agregando otra solución si está usando storyboards. Cree una subclase de UIView que no permita establecer el backgroundColor una vez que se haya configurado inicialmente.

@interface ConstBackgroundColorView : UIView @end @implementation ConstBackgroundColorView - (void)setBackgroundColor:(UIColor *)backgroundColor { if (nil == self.backgroundColor) { [super setBackgroundColor:backgroundColor]; } } @end


Basado en la respuesta de Paul Gurov implementé lo siguiente en Xamarin.iOS. Versión C #:

NeverClearView.cs

public partial class NeverClearView : UIView { public NeverClearView(IntPtr handle) : base(handle) { } public override UIColor BackgroundColor { get { return base.BackgroundColor; } set { if (value.CGColor.Alpha == 0) return; base.BackgroundColor = value; } } }

NeverClearView.designer.cs

[Register("NeverClearView")] partial class NeverClearView { void ReleaseDesignerOutlets() { } }


Coloque este código en su subclase de UITableViewCell

Sintaxis de Swift 3

override func setSelected(_ selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) if(selected) { lockerSmall.backgroundColor = UIColor.init(red: 233/255, green: 106/255, blue: 49/255, alpha: 1.0) } } override func setHighlighted(_ highlighted: Bool, animated: Bool) { super.setHighlighted(highlighted, animated: animated) if(highlighted) { lockerSmall.backgroundColor = UIColor.init(red: 233/255, green: 106/255, blue: 49/255, alpha: 1.0) } }


Dibuje la vista en lugar de establecer el color de fondo

import UIKit class CustomView: UIView { var fillColor:UIColor! convenience init(fillColor:UIColor!) { self.init() self.fillColor = fillColor } override func drawRect(rect: CGRect) { if let fillColor = fillColor { let context = UIGraphicsGetCurrentContext() CGContextSetFillColorWithColor(context, fillColor.CGColor); CGContextFillRect (context, self.bounds); } } }


Encontré una solución bastante elegante en lugar de jugar con los métodos de selección / resaltado tableViewCell. Puede crear una subclase de UIView que ignore establecer su color de fondo para borrar el color.

Swift 3/4:

class NeverClearView: UIView { override var backgroundColor: UIColor? { didSet { if backgroundColor != nil && backgroundColor!.cgColor.alpha == 0 { backgroundColor = oldValue } } } }

Swift 2:

class NeverClearView: UIView { override var backgroundColor: UIColor? { didSet { if CGColorGetAlpha(backgroundColor!.CGColor) != 0 { backgroundColor = oldValue } } } }

Versión Obj-C:

@interface NeverClearView : UIView @end @implementation NeverClearView - (void)setBackgroundColor:(UIColor *)backgroundColor { if (CGColorGetAlpha(backgroundColor.CGColor) != 0) { [super setBackgroundColor:backgroundColor]; } } @end


Es porque la celda de vista de tabla cambia automáticamente el color de fondo de todas las vistas dentro de la vista de contenido para el estado resaltado. Puede considerar subclasificar a UIView para dibujar su color o usar UIImageView con una imagen personalizada de 1x1 px.


Esto es similar a la respuesta de Pavel Gurov, pero es más flexible ya que permite que cualquier color sea permanente.

class PermanentBackgroundColorView: UIView { var permanentBackgroundColor: UIColor? { didSet { backgroundColor = permanentBackgroundColor } } override var backgroundColor: UIColor? { didSet { if backgroundColor != permanentBackgroundColor { backgroundColor = permanentBackgroundColor } } } }


Inspirado por la de , creé una categoría / extensión UITableViewCell que le permite activar y desactivar esta "función" de transparencia.

Rápido

let cell = <Initialize Cell> cell.keepSubviewBackground = true // Turn transparency "feature" off cell.keepSubviewBackground = false // Leave transparency "feature" on

C objetivo

UITableViewCell* cell = <Initialize Cell> cell.keepSubviewBackground = YES; // Turn transparency "feature" off cell.keepSubviewBackground = NO; // Leave transparency "feature" on

KeepBackgroundCell es compatible con CocoaPods. Puedes encontrarlo en GitHub


Inspirado por la respuesta de Yatheesha BL .

Si llama a super.setSelected (seleccionado, animado: animado), borrará todo el color de fondo que configure . Por lo tanto, no llamaremos supermétodo.

En Swift:

override func setSelected(selected: Bool, animated: Bool) { if(selected) { contentView.backgroundColor = UIColor.red } else { contentView.backgroundColor = UIColor.white } } override func setHighlighted(highlighted: Bool, animated: Bool) { if(highlighted) { contentView.backgroundColor = UIColor.red } else { contentView.backgroundColor = UIColor.white } }


No olvides anular setSelected así como setHighlighted

override func setHighlighted(highlighted: Bool, animated: Bool) { super.setHighlighted(highlighted, animated: animated) someView.backgroundColor = .myColour() } override func setSelected(selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) someView.backgroundColor = .myColour() }


Otra forma de gestionar el problema es llenar la vista con un degradado de gráficos centrales, como:

CAGradientLayer* gr = [CAGradientLayer layer]; gr.frame = mySubview.frame; gr.colors = [NSArray arrayWithObjects: (id)[[UIColor colorWithRed:0 green:0 blue:0 alpha:.5] CGColor] ,(id)[[UIColor colorWithRed:0 green:0 blue:0 alpha:.5] CGColor] , nil]; gr.locations = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0],[NSNumber numberWithFloat:1],nil]; [mySubview.layer insertSublayer:gr atIndex:0];


Para Swift 2.2 esto funciona

cell.selectionStyle = UITableViewCellSelectionStyle.None

y la razón es explicada por @ Andriy

Es porque la celda de vista de tabla cambia automáticamente el color de fondo de todas las vistas dentro de la vista de contenido para el estado resaltado.


Prueba el siguiente código:

-(void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated { [super setHighlighted:highlighted animated:animated]; //Set your View''s Color here. }


Puede cell.selectionStyle = UITableViewCellSelectionStyleNone; , luego configure backgroundColor en - (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath


Quería mantener el comportamiento de selección predeterminado a excepción de una subvista de celda que quería ignorar el cambio automático de color de fondo. Pero también necesitaba poder cambiar el color de fondo en otros momentos.

La solución que se me ocurrió fue subclasificar a UIView por lo que ignora el ajuste del color de fondo normalmente y agrega una función separada para eludir la protección.

Swift 4

class MyLockableColorView: UIView { func backgroundColorOverride(_ color: UIColor?) { super.backgroundColor = color } override var backgroundColor: UIColor? { set { return } get { return super.backgroundColor } } }


Si la solución de fondo mencionada anteriormente no está solucionando su problema, su problema puede estar en su fuente de datasource para su tableView.

Para mí, estaba creando una instancia de un objeto DataSource (llamado BoxDataSource ) para manejar los métodos delegate y dataSource tableView, así:

//In cellForRowAtIndexPath, when setting up cell let dataSource = BoxDataSource(delegate: self) cell.tableView.dataSource = dataSource return cell

Esto causaba que el dataSource fuera desasignado cada vez que se tocaba la celda y, por lo tanto, todos los contenidos desaparecían. La razón es, es ARC la deslocalización / recolección de basura naturaleza.

Para solucionar esto, tuve que ir a la celda personalizada, agregar una variable de origen de datos:

//CustomCell.swift var dataSource: BoxDataSource?

Luego, debe configurar el dataSource en la fuente dataSource de la celda que acaba de crear en cellForRow, por lo que no se desasignará con ARC.

cell.statusDataSource = BoxAssigneeStatusDataSource(delegate: self) cell.detailsTableView.dataSource = cell.statusDataSource return cell

Espero que ayude.


UITableViewCell cambia el color de fondo de todas las subvistas en la selección por algún motivo.

Esto podría ayudar:

DVColorLockView

Use algo así para evitar que UITableView cambie el color de su vista durante la selección.


aquí está mi solución, use contentView para mostrar selectionColor, funciona perfectamente

#import "BaseCell.h" @interface BaseCell () @property (nonatomic, strong) UIColor *color_normal; @property (nonatomic, assign) BOOL needShowSelection; @end @implementation BaseCell @synthesize color_customSelection; @synthesize color_normal; @synthesize needShowSelection; - (void)awakeFromNib { [super awakeFromNib]; [self setup]; } - (void)setup { //save normal contentView.backgroundColor self.color_normal = self.backgroundColor; if (self.color_normal == nil) { self.color_normal = [UIColor colorWithRGBHex:0xfafafa]; } self.color_customSelection = [UIColor colorWithRGBHex:0xF1F1F1]; self.accessoryView.backgroundColor = [UIColor clearColor]; if (self.selectionStyle == UITableViewCellSelectionStyleNone) { needShowSelection = NO; } else { //cancel the default selection needShowSelection = YES; self.selectionStyle = UITableViewCellSelectionStyleNone; } } /* solution is here */ - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [super touchesBegan:touches withEvent:event]; if (needShowSelection) { self.contentView.backgroundColor = self.backgroundColor = color_customSelection; } } - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { [super touchesCancelled:touches withEvent:event]; if (needShowSelection) { self.contentView.backgroundColor = self.backgroundColor = color_normal; } } - (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated]; if (needShowSelection) { UIColor *color = selected ? color_customSelection:color_normal; self.contentView.backgroundColor = self.backgroundColor = color; } }


UITableViewCell cambia el color de fondo de todas las vistas secundarias cuando se selecciona o resalta la celda. Puede resolver este problema anulando el color de fondo de vista de la celda de setSelected:animated y setHighlighted:animated restablecido.

En el Objetivo C:

- (void)setSelected:(BOOL)selected animated:(BOOL)animated { UIColor *color = self.yourView.backgroundColor; [super setSelected:selected animated:animated]; if (selected){ self.yourView.backgroundColor = color; } } -(void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated{ UIColor *color = self.yourView.backgroundColor; [super setHighlighted:highlighted animated:animated]; if (highlighted){ self.yourView.backgroundColor = color; } }

En Swift 3.1:

override func setSelected(_ selected: Bool, animated: Bool) { let color = yourView.backgroundColor super.setSelected(selected, animated: animated) if selected { yourView.backgroundColor = color } } override func setHighlighted(_ highlighted: Bool, animated: Bool) { let color = yourView.backgroundColor super.setHighlighted(highlighted, animated: animated) if highlighted { yourView.backgroundColor = color } }