como posso detectar o evento de toque de um UIImageView

97

Coloquei uma imagem (UIImageView) na barra de navegação. Agora quero detectar o evento de toque e controlar o evento. Você poderia me dizer como posso fazer isso?

Obrigado.

ebaccount
fonte
Nessa situação, eu usaria (e acho que você deveria) usar um UIButton personalizado.
titaniumdecoy
Verifique a versão Swift. Resposta http://stackoverflow.com/a/41328885/3177007
Mohamed Jaleel Nazir

Respostas:

137

Em termos práticos, não faça isso.

Em vez disso, adicione um botão com estilo personalizado (sem gráficos de botão, a menos que você especifique imagens) sobre o UIImageView. Em seguida, anexe quaisquer métodos que você deseja chamar para isso.

Você pode usar essa técnica para muitos casos em que realmente deseja que alguma área da tela atue como um botão em vez de mexer com o toque.

Kendall Helmstetter Gelner
fonte
Eu adicionei um botão na barra de navegação e também posso lidar com eventos de toque. No entanto, quero adicionar uma imagem redonda a este botão. Você poderia me informar como posso fazer isso de forma programática? Além disso, você poderia me informar como posso definir a propriedade do botão como "personalizado" de forma programática?
ebaccount
Olhe a documentação do UIButton - você precisa definir imagens de fundo para um estado de controle, você vai querer imagens diferentes para Normal vs. Selecionado / Destacado. O estilo do botão é o que você define como UIButtonStyleCustom, eu acredito - novamente, olhe os documentos para a propriedade de estilo no UIButton.
Kendall Helmstetter Gelner
1
Adicionar um UIButton no topo do UIImageView não é um pouco exagerado? Você está adicionando um objeto extra, embora possa apenas implementar os métodos de toque do objeto UIImageView já existente. Não?
samvermette de
32
Se você olhar para o tamanho de um UIButton na memória, é virtualmente nada e você só tem alguns por tela. O que você obtém de graça é toda a fiação de ação do alvo para diferentes estados (como o toque interno) e também um comportamento agradável, como não disparar quando você pressiona, mas desliza um dedo para o lado. Basicamente, os botões são um dos objetos mais bem elaborados em todo o sistema e pensar que você vai fazer um código de toque personalizado que funcione melhor é uma loucura. Use o que é barato e funciona bem, guarde o trabalho personalizado para coisas que os frameworks ainda não tratam para você.
Kendall Helmstetter Gelner
6
Você também pode sobrepor um UIControl se tudo o que você precisa são eventos de toque (via addTaget: action: forControlEvents :). É um pouco mais barato que um UIButton que tem imagens e vários estados. Além disso, eu uso condicionais de pré-processador para alterar a cor de fundo do controle sobreposto para rosa, para que eu possa ver exatamente onde eles estão (e lembrar que existem :-).
Jeff de
115

A UIImageViewé derivado de a UIViewque é derivado de, UIResponderportanto, está pronto para lidar com eventos de toque. Você vai querer fornecer os touchesBegan, touchesMovede touchesEndedmétodos e eles vão obter chamado se o usuário toca a imagem. Se tudo o que você deseja é um evento de toque, é mais fácil apenas usar um botão personalizado com a imagem definida como a imagem do botão. Mas se você quiser um controle de grão mais fino sobre torneiras, movimentos, etc., este é o caminho a percorrer.

Você também vai querer ver mais algumas coisas:

  • Substitua canBecomeFirstRespondere retorne SIM para indicar que a visualização pode se tornar o foco dos eventos de toque (o padrão é NÃO).

  • Defina a userInteractionEnabledpropriedade como SIM. O padrão para UIViewsé SIM, mas para UIImageViewsNÃO, então você deve ativá-lo explicitamente.

  • Se você deseja responder a eventos multitoque (ou seja, apertar, zoom, etc), você deve definir multipleTouchEnabledcomo SIM.

Ramin
fonte
Tentei fazer isso, mas não recebo os eventos do touchesBegan ... por que isso?
Markus
5
@Markus: Eu tive o mesmo problema, mas resolvi definindo userInteractionEnabledcomo SIM na minha visualização dos pais. Consulte stackoverflow.com/questions/5887305/…
Saxon Druce
51

Para adicionar um evento de toque a um UIImageView use o seguinte em seu .m

UITapGestureRecognizer *newTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(myTapMethod)];

[myImageView setUserInteractionEnabled:YES];

[myImageView addGestureRecognizer:newTap];


-(void)myTapMethod{
    // treat image tap
}

espero que ajude.

Sim.
fonte
userInteractionEnabled = true é a parte que é fácil de esquecer, obrigado.
Michael Peterson
23

Você também pode adicionar um UIGestureRecognizer. Ele não exige que você adicione um elemento adicional em sua hierarquia de visualização, mas ainda fornece a você todo o código bem escrito para lidar com eventos de toque com uma interface bastante simples:

    UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc]
                                            initWithTarget:self action:@selector(handleSwipe:)];
    swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
    [imgView_ addGestureRecognizer:swipeRight];        
    [swipeRight release];
    UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc]
                                            initWithTarget:self action:@selector(handleSwipe:)];
    swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
    [imgView_ addGestureRecognizer:swipeLeft];
    [swipeLeft release];
Spolu
fonte
10
NÃO se esqueça de definir UserInteractionEnabled para imgView_
Anonymous White
13

Estive em diferentes tópicos nas últimas horas tentando encontrar uma solução para o meu problema, sem sucesso. Vejo que muitos desenvolvedores compartilham esse problema e acho que as pessoas aqui sabem disso. Tenho várias imagens dentro de um UIScrollView, tentando obter eventos de toque nelas.

não obtendo eventos de um UIImangeView, mas recebo um evento de um semelhante UILablecom parâmetros muito semelhantes que estou definindo para ele. sob IOS 5.1.

Já fiz o seguinte:

  1. defina setUserInteractionEnabled como YES para `UIImageView e visualização pai.
  2. defina setMultipleTouchEnabled como YES para UIImageView.
  3. Tentei UIImageViewcriar subclasses , mas não ajudou em nada.

Anexando algum código abaixo, neste código eu inicializo a UIImageViewe UILabel, o rótulo funciona bem em termos de eventos de disparo. Tentei evitar códigos irrelevantes. Obrigado pessoal Ilan

UIImageView *single_view = [[UIImageView alloc]initWithFrame:CGRectMake(200, 200, 100, 100)];
single_view.image=img;
single_view.layer.zPosition=4;

UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapGestureCaptured:)];
[single_view addGestureRecognizer:singleTap];
[single_view setMultipleTouchEnabled:YES];
[single_view setUserInteractionEnabled:YES];
[self.myScrollView addSubview:single_view];    
self.myScrollView.userInteractionEnabled=YES;

UILabel *testLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
testLabel.backgroundColor=[UIColor redColor];
[self.myScrollView addSubview:testLabel];
[testLabel addGestureRecognizer:singleTap];  
[testLabel setMultipleTouchEnabled:YES];
[testLabel setUserInteractionEnabled:YES];
testLabel.layer.zPosition=4;

E o método que trata o evento:

- (void)singleTapGestureCaptured:(UITapGestureRecognizer *)gesture
{ 
    UIView *tappedView = [gesture.view hitTest:[gesture locationInView:gesture.view] withEvent:nil];
    NSLog(@"Touch event on view: %@",[tappedView class]);
}

Como disse, a torneira de etiqueta é recebida.

ilan
fonte
6

Em vez de fazer um UIImageView tocável e colocá-lo na barra de navegação, você deve apenas criar um UIBarButtonItem, que pode ser feito a partir de um UIImageView.

Primeiro faça a visualização da imagem:

UIImageView *yourImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"nameOfYourImage.png"]];

Em seguida, faça o item barbutton fora de sua visualização de imagem:

UIBarButtonItem *yourBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:yourImageView];

Em seguida, adicione o item do botão da barra à sua barra de navegação:

self.navigationItem.rightBarButtonItem = yourBarButtonItem;

Lembre-se de que esse código vai para o controlador de visualização, que está dentro de um array de controlador de visualização do controlador de navegação. Então, basicamente, este "item de botão da barra de aparência de imagem tocável" só aparecerá na barra de navegação quando este controlador de visualização estiver sendo mostrado. Quando você pressiona outro controlador de visualização, este item do botão da barra de navegação irá desaparecer ~

Yujean
fonte
3

O que você pode querer fazer é substituir o touchesBegan:withEvent:método da UIView(ou subclasse) que contém sua UIImageViewsubvisão.

Dentro desse método, teste se algum dos UITouchtoques está dentro dos limites da UIImageViewinstância (digamos que seja chamado imageView).

Ou seja, o CGPointelemento faz [touch locationInView]interseção com o CGRectelemento [imageView bounds]? Verifique a função CGRectContainsPointpara executar este teste.

Alex Reynolds
fonte
Obrigado pela sua resposta. Eu adicionei a exibição como esta: [navBar addSubview: self.pImage]; // adicionado como uma subvisão da barra de navegação. Substituí a função, mas ela nunca é chamada. Eu defini a propriedade userInteractionEnabled do UIImageView como YES. Estou perdendo alguma coisa?
ebaccount
Confira o método touchesBegan: withEvent :. Existem muitos exemplos em mecanismos de pesquisa de como isso funciona.
Alex Reynolds
1

Primeiro você deve colocar um UIButton e então pode adicionar uma imagem de fundo para este botão ou você precisa colocar um UIImageView sobre o botão.

ou

Você pode adicionar o gesto de toque a um UIImageView para obter a ação de clique ao tocar no UIImageView.

Hilaj
fonte
0

Para aqueles que procuram uma solução Swift 4 para esta resposta. Você pode usar o seguinte para detectar um evento de toque em um UIImageView.

let gestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageViewTapped))
imageView.addGestureRecognizer(gestureRecognizer)
imageView.isUserInteractionEnabled = true

Você precisará definir seu seletor da seguinte maneira:

@objc func imageViewTapped() {
    // Image has been tapped
}
Josh
fonte
-2

Adicione um gesto nessa imagem view.add nessa visualização, então ele detectaria um gesto na imagem também. Você pode tentar com o método delegado de evento de toque, então, nesse caso, ele também pode estar detectando. obrigado

user1240409
fonte