como posso detectar o evento de toque de um UIImageView


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.


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.


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.


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];

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.


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 ~


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.


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.


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
}

-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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.