Eu tenho um UITableView
com 5 UITableViewCells
. Cada célula contém um UIButton
que é configurado da seguinte maneira:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier = @"identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
[cell autorelelase];
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 5, 40, 20)];
[button addTarget:self action:@selector(buttonPressedAction:) forControlEvents:UIControlEventTouchUpInside];
[button setTag:1];
[cell.contentView addSubview:button];
[button release];
}
UIButton *button = (UIButton *)[cell viewWithTag:1];
[button setTitle:@"Edit" forState:UIControlStateNormal];
return cell;
}
Minha pergunta é a seguinte: no buttonPressedAction:
método, como sei qual botão foi pressionado. Eu considerei usar tags, mas não tenho certeza se esse é o melhor caminho. Eu gostaria de poder, de alguma forma, marcar indexPath
o comando no controle.
- (void)buttonPressedAction:(id)sender
{
UIButton *button = (UIButton *)sender;
// how do I know which button sent this message?
// processing button press for this row requires an indexPath.
}
Qual é a maneira padrão de fazer isso?
Editar:
Eu meio que resolvi fazendo o seguinte. Eu ainda gostaria de ter uma opinião se essa é a maneira padrão de fazê-lo ou se existe uma maneira melhor?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier = @"identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
[cell autorelelase];
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 5, 40, 20)];
[button addTarget:self action:@selector(buttonPressedAction:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:button];
[button release];
}
UIButton *button = (UIButton *)[cell.contentView.subviews objectAtIndex:0];
[button setTag:indexPath.row];
[button setTitle:@"Edit" forState:UIControlStateNormal];
return cell;
}
- (void)buttonPressedAction:(id)sender
{
UIButton *button = (UIButton *)sender;
int row = button.tag;
}
O que é importante observar é que não posso definir a marca na criação da célula, pois ela pode ser desenfileirada. Parece muito sujo. Deve haver uma maneira melhor.
ios
iphone
uitableview
uibutton
rédea
fonte
fonte
Respostas:
Na amostra de acessórios da Apple, o seguinte método é usado:
Em seguida, no manipulador de toque, coordenada de toque recuperada e o caminho do índice é calculado a partir dessa coordenada:
fonte
Eu encontrei o método de usar a superview da superview para obter uma referência ao indexPath da célula funcionou perfeitamente. Agradecimentos a iphonedevbook.com (macnsmith) pelo texto do link da dica
fonte
Aqui está como eu faço isso. Simples e conciso:
fonte
CGPointZero
em vez deCGPointMake(0, 0)
;-)Encontrei uma boa solução para esse problema em outro lugar, sem mexer nas tags no botão:
fonte
buttonPressedAction:
masbuttonPressedAction:forEvent:
.Que tal enviar informações como
NSIndexPath
naUIButton
injeção de tempo de execução.1) Você precisa de tempo de execução na importação
2) adicione constante estática
3) adicione
NSIndexPath
ao seu botão no tempo de execução usando:(void) setMetaData: (id) destino comObject: (id) newObj
4) ao pressionar o botão obter metadados usando:
(id) metaData: (id) destino
Aproveitar
fonte
To do (@Vladimir), a resposta é Swift:
Embora a verificação
indexPath != nil
me dê o dedo ... "NSIndexPath não é um subtipo de NSString"fonte
Com o Swift 4.2 e iOS 12, você pode escolher um dos 5 exemplos completos a seguir para resolver seu problema.
# 1 Usando
UIView
'sconvert(_:to:)
eUITableView
' sindexPathForRow(at:)
# 2 Usando
UIView
'sconvert(_:to:)
eUITableView
' sindexPathForRow(at:)
(alternativa)Esta é uma alternativa ao exemplo anterior, onde passamos
nil
aotarget
parâmetro noaddTarget(_:action:for:)
. Dessa forma, se o primeiro respondedor não implementar a ação, ele será enviado para o próximo respondente na cadeia de respondentes até que uma implementação adequada seja encontrada.# 3 Usando
UITableView
'sindexPath(for:)
e padrão de delegadoNeste exemplo, definimos o controlador de exibição como o delegado da célula. Quando o botão da célula é tocado, ele aciona uma chamada para o método apropriado do delegado.
# 4 Usando
UITableView
'sindexPath(for:)
e um fecho para delegaçãoEsta é uma alternativa ao exemplo anterior, em que usamos um fechamento em vez de uma declaração de delegado de protocolo para manipular o toque no botão.
# 5 Usando
UITableViewCell
'saccessoryType
eUITableViewDelegate
' stableView(_:accessoryButtonTappedForRowWith:)
Se o seu botão é um
UITableViewCell
's controle acessório padrão, qualquer toque nele irá desencadear uma chamada paraUITableViewDelegate
' stableView(_:accessoryButtonTappedForRowWith:)
, o que lhe permite obter o caminho índice relacionado.fonte
fonte
Eu usaria a propriedade tag como você disse, definindo a tag da seguinte maneira:
e colocar a tag dentro do buttonPressedAction da seguinte maneira:
Ou
fonte
tag
é um número inteiro. parece um pouco desajeitado codificar / decodificar os caminhos do índice nas tags de exibição.Embora eu goste da maneira como as tags ... se você não quiser usar tags por qualquer motivo, poderá criar um membro
NSArray
de botões pré-fabricados:crie esses botões antes de renderizar o tableView e envie-os para a matriz.
Então, dentro da
tableView:cellForRowAtIndexPath:
função, você pode fazer:Então, na
buttonPressedAction:
função, você pode fazerfonte
PARA MANUSEAR SEÇÕES - Eu armazenei o NSIndexPath em um UITableViewCell personalizado
IN CLKIndexPricesHEADERTableViewCell.xib
IN IB Adicione UIButton ao XIB - NÃO adicione ação!
Adicione a saída @ propriedade (reter, não atômica) IBOutlet UIButton * buttonIndexSectionClose;
NÃO CTRL + DRAG uma ação no IB (feita no código abaixo)
Em viewForHeaderInSection (também deve funcionar para cellForRow .... etc, se a tabela tiver apenas 1 seção)
... use a seção para obter dados para o seu celular
... preencha
USER pressiona o botão DELETE no cabeçalho da seção e isso chama
Neste exemplo, adicionei um botão Excluir para exibir o UIAlertView para confirmar
Eu guardo a seção e digito no dicionário o armazenamento de informações sobre a seção em um ivar no VC
fonte
fonte
Funciona para mim também, obrigado @Cocoanut
Eu encontrei o método de usar a superview da superview para obter uma referência ao indexPath da célula funcionou perfeitamente. Agradecimentos a iphonedevbook.com (macnsmith) pelo texto do link da dica
fonte
você pode usar o padrão de tag:
fonte
Estou esquecendo de algo? Você não pode simplesmente usar o remetente para identificar o botão. O remetente fornecerá informações como esta:
Então, se você quiser alterar as propriedades do botão, diga a imagem de plano de fundo que acabou de dizer ao remetente:
Se você precisar da tag, o método do ACBurk está correto.
fonte
Bem simples, na verdade:
Trabalhando bem para mim: P
se você quiser ajustar sua configuração de ação de destino, poderá incluir o parâmetro de evento no método e, em seguida, usar os toques desse evento para resolver as coordenadas do toque. As coordenadas ainda precisam ser resolvidas nos limites da visualização por toque, mas isso pode parecer mais fácil para algumas pessoas.
fonte
crie uma matriz nsmutable e coloque todos os botões nessa matriz usint [array addObject: yourButton];
no método de pressionar o botão
-
fonte
Uma pequena variação na resposta dos Cocoanuts (que me ajudou a resolver isso) quando o botão estava no rodapé de uma tabela (o que impede você de encontrar a 'célula clicada':
fonte
Eu sempre uso tags.
Você precisa subclassificar
UITableviewCell
e manipular o botão pressionado a partir daí.fonte
É simples; crie uma célula personalizada e retire o botão
altere o ID no método acima para
(UIButton *)
Você pode obter o valor em que botão está sendo pressionado executando sender.tag.
fonte
Subclasse o botão para armazenar o valor necessário, talvez crie um protocolo (ControlWithData ou algo assim). Defina o valor ao adicionar o botão à célula de exibição de tabela. No evento de retoque, verifique se o remetente obedece ao protocolo e extrai os dados. Normalmente, guardo uma referência ao objeto real que é renderizado na célula de exibição de tabela.
fonte
ATUALIZAÇÃO SWIFT 2
Aqui está como descobrir qual botão foi tocado + enviar dados para outro ViewController a partir desse botão,
indexPath.row
pois estou assumindo que esse é o ponto para a maioria!Para aqueles que estão usando uma classe ViewController e adicionaram um tableView, estou usando um ViewController em vez de um TableViewController, então adicionei manualmente o tableView para acessá-lo.
Aqui está o código para passar dados para outro VC ao tocar nesse botão e passar a célula
indexPath.row
fonte
Observe aqui que estou usando uma célula personalizada. Este código está funcionando perfeitamente para mim.
fonte
A solução de Chris Schwerdt, mas depois em Swift, funcionou para mim:
fonte
Este problema tem duas partes:
1) Obtendo o caminho do índice
UITableViewCell
que contém pressionadoUIButton
Existem algumas sugestões como:
Atualização
UIButton
étag
nocellForRowAtIndexPath:
método utilizando do caminho de índicerow
de valor. Esta não é uma boa solução, pois requer atualizaçãotag
contínua e não funciona com exibições de tabela com mais de uma seção.Adicionando uma
NSIndexPath
propriedade para celular personalizado e atualizá-lo em vez deUIButton
'stag
nocellForRowAtIndexPath:
método. Isso resolve o problema de várias seções, mas ainda não é bom, pois exige atualização sempre.Manter uma referência fraca ao pai
UITableView
na célula personalizada enquanto a cria e usa oindexPathForCell:
método para obter o caminho do índice. Parece um pouco melhor, não há necessidade de atualizar nada nocellForRowAtIndexPath:
método, mas ainda requer a definição de uma referência fraca quando a célula personalizada é criada.Usando a
superView
propriedade da célula para obter uma referência ao paiUITableView
. Não é necessário adicionar propriedades à célula personalizada e não é necessário definir / atualizar nada na criação / posteriormente. Mas a célulasuperView
depende dos detalhes de implementação do iOS. Portanto, não pode ser usado diretamente.Mas isso pode ser alcançado usando um loop simples, pois temos certeza de que a célula em questão deve estar em um UITableView:
Portanto, essas sugestões podem ser combinadas em um método de célula personalizado simples e seguro para obter o caminho do índice:
A partir de agora, este método pode ser usado para detectar qual
UIButton
é pressionado.2) Informar outras partes sobre o evento de pressionar o botão
Depois de saber internamente qual
UIButton
é pressionado em qual célula personalizada com o caminho exato do índice, essas informações precisam ser enviadas para outras partes (provavelmente o controlador de exibição que manipula oUITableView
). Portanto, esse evento de clique no botão pode ser tratado em um nível de abstração e lógica semelhante aodidSelectRowAtIndexPath:
método do delegado do UITableView.Duas abordagens podem ser usadas para isso:
a) Delegação: a célula personalizada pode ter uma
delegate
propriedade e definir um protocolo. Quando o botão é pressionado, ele apenas executa seus métodos de delegação em suadelegate
propriedade. Mas essadelegate
propriedade precisa ser configurada para cada célula customizada quando elas são criadas. Como alternativa, a célula personalizada também pode optar por executar seus métodos de delegação nas visualizações da tabela paidelegate
.b) Centro de Notificação: as células personalizadas podem definir um nome de notificação personalizado e postar essa notificação com o caminho do índice e as informações de exibição da tabela pai fornecidas no
userInfo
objeto. Não é necessário definir nada para cada célula, basta adicionar um observador para a notificação da célula personalizada.fonte
Eu uso uma solução que subclasse
UIButton
e pensei que deveria compartilhá-lo aqui, códigos em Swift:Lembre-se de atualizar seu indexPath em
cellForRow(at:)
Portanto, ao responder ao evento do botão, você pode usá-lo como
fonte