Imagem de checkbox de seleção alterna no UITableViewCell

Preciso de alguma orientação sobre como criar um UITableViewCell que tenha uma imagem à esquerda que possa ser alternada. A imagem deve ser tocada e atuar como uma alternância (checkbox de seleção).

Minhas partes que estou lutando são:

  1. Como faço para detectar toques na imagem e lidar com isso de maneira diferente do didSelectRowAtIndexPath?
  2. Como faço para alterar a imagem sem executar um [tableView reloadData]?

Veja a imagem abaixo para um exemplo:

texto alternativo http://sofpt.miximages.com/iphone/screenshotkmr.png

obrigado

Na verdade é bem fácil.

Basta criar uma nova subclass do UIControl e colocar tudo ali (sem necessidade de um controlador separado). Vamos chamá-lo de ToggleImageControl.

@interface ToggleImageControl : UIControl { BOOL selected; UIImageView *imageView; UIImage *normalImage; UIImage *selectedImage; } 

Crie um ToggleImageControl para cada célula e adicione-o na posição apropriada.

 ToggleImageControl *toggleControl = [[ToggleImageControl alloc] initWithFrame: ]; toggleControl.tag = indexPath.row; // for reference in notifications. [cell.contentView addSubview: toggleControl]; 

Adicione um UIImageView para conter a imagem. Adicione um alvo para o evento de toque.

 - (void) viewDidLoad { normalImage = [UIImage imageNamed: @"normal.png"]; selectedImage = [UIImage imageNamed: @"selected.png"]; imageView = [[UIImageView alloc] initWithImage: normalImage]; // set imageView frame [self.view addSubview: imageView]; [self addTarget: self action: @selector(toggleImage) forControlEvents: UIControlEventTouchUpInside]; } 

Defina a propriedade de imagem do UIImageView para atualizar a imagem; que acionará o redesenho sem efeitos colaterais.

 - (void) toggleImage { selected = !selected; imageView.image = (selected ? selectedImage : normalImage); // Use NSNotification or other method to notify data model about state change. // Notification example: NSDictionary *dict = [NSDictionary dictionaryWithObject: [NSNumber numberWithInt: self.tag forKey: @"CellCheckToggled"]; [[NSNotificationCenter defaultCenter] postNotificationName: @"CellCheckToggled" object: self userInfo: dict]; } 

Você obviamente precisará massagear algumas coisas. Você provavelmente deseja passar os dois nomes de imagem para torná-lo mais reutilizável e também recomendo que você especifique a string de nome da notificação fora do object (supondo que esteja usando o método de notificação).

Aqui está uma implementação da abordagem “override touchesBegan:” que estou usando, que é simples e parece funcionar bem.

Basta include essa class em seu projeto e criar e configurar um TouchIconTableViewCell vez de uma célula UITableView no método tableView:cellForRowAtIndexPath:

TouchIconTableViewCell.h:

 #import  @class TouchIconTableViewCell; @protocol TouchIconTableViewCellDelegate @required - (void)tableViewCellIconTouched:(TouchIconTableViewCell *)cell indexPath:(NSIndexPath *)indexPath; @end @interface TouchIconTableViewCell : UITableViewCell { id touchIconDelegate; // note: not retained NSIndexPath *touchIconIndexPath; } @property (nonatomic, assign) id touchIconDelegate; @property (nonatomic, retain) NSIndexPath *touchIconIndexPath; @end 

TouchIconTableViewCell.m:

 #import "TouchIconTableViewCell.h" @implementation TouchIconTableViewCell @synthesize touchIconDelegate; @synthesize touchIconIndexPath; - (void)dealloc { [touchIconIndexPath release]; [super dealloc]; } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { CGPoint location = [((UITouch *)[touches anyObject]) locationInView:self]; if (CGRectContainsPoint(self.imageView.frame, location)) { [self.touchIconDelegate tableViewCellIconTouched:self indexPath:self.touchIconIndexPath]; return; } [super touchesBegan:touches withEvent:event]; } @end 

Sempre que você criar ou reutilizar a célula, defina as propriedades touchIconIndexPath e touchIconIndexPath . Quando o seu ícone é tocado, o delegado será invocado. Então você pode atualizar o ícone ou o que quer que seja.

Então o “..obviamente precisa massagear algumas coisas ..” comentário significa “… este código não funciona …”.

assim

 - (void) viewDidLoad 

deveria estar

 - (id)initWithFrame:(CGRect)frame { if ( self = [super initWithFrame: frame] ){ normalImage = [UIImage imageNamed: @"toggleImageNormal.png"]; selectedImage = [UIImage imageNamed: @"toggleImageSelected.png"]; imageView = [[UIImageView alloc] initWithImage: normalImage]; // set imageView frame [self addSubview: imageView]; [self addTarget: self action: @selector(toggleImage) forControlEvents: UIControlEventTouchDown]; } return self; } 

As - (void) viewDidLoad nunca é chamado.

Parece que a Apple carregou “TableMultiSelect” como códigos de amostra no iOS Developer Program desde 2011-10-12.

Múltipla seleção no modo de edição pode ser ativada por este código.

 self.tableView.allowsMultipleSelectionDuringEditing = YES; 

http://developer.apple.com/library/ios/#samplecode/TableMultiSelect/Introduction/Intro.html

Embora possa ser usado apenas no iOS5.

Várias horas eu não consegui encontrar este código de exemplo no Stack Overflow, então eu adicionei esta informação a este post.

Há uma maneira ainda mais fácil de fazer isso, se você replace o CookBegan: você precisa fazer uma declaração if para decidir se ele está dentro da proximidade, se não é chamado [super touchesBegan:touches withEvent:event] e ele vai agir como se foi selecionado.

Eu faço algo semelhante (estrelado por um favorito) como este, mas eu acho que você está exigindo muito dos polegares dos usuários do iPhone com a célula direcionando as pessoas para outra visão. Primeiro de tudo, gostaria de verificar a opção de divulgação de detalhes nas células. Uma das opções é um botão de seta pré-fabricado que você pode append. Sua chamada.

Você pode conseguir pegar o evento didSelectRowAtIndexPath e fazer alguma outra lógica em vez de redirect se o toque estiver na sua checkbox de seleção, embora eu não saiba como você conseguiria a posição. Isso significa que você pode precisar encontrar uma maneira de obter o evento de toque antes de chamar o caminho didSelectRowAtIndex, que não tenho certeza de como fazer. Você já trabalhou com o manuseio de produtos vegetarianos e similares?