Wie kann ich das Berührungsereignis eines UIImageView erkennen?

98

Ich habe ein Bild (UIImageView) in der Navigationsleiste platziert. Jetzt möchte ich das Berührungsereignis erkennen und das Ereignis behandeln. Könnten Sie mich wissen lassen, wie ich das machen kann?

Vielen Dank.

ebaccount
quelle
In dieser Situation würde ich (und denke, Sie sollten) stattdessen einen benutzerdefinierten UIButton verwenden.
titaniumdecoy
Überprüfen Sie Swift-Version Antwort http://stackoverflow.com/a/41328885/3177007
Mohamed Jaleel Nazir

Antworten:

137

In der Praxis tun Sie das nicht.

Fügen Sie stattdessen eine Schaltfläche mit benutzerdefiniertem Stil (keine Schaltflächengrafiken, es sei denn, Sie geben Bilder an) über UIImageView hinzu. Fügen Sie dann die gewünschten Methoden hinzu.

Sie können diese Technik in vielen Fällen verwenden, in denen Sie wirklich möchten, dass ein Bereich des Bildschirms als Schaltfläche fungiert, anstatt mit dem Touch-Material herumzuspielen.

Kendall Helmstetter Gelner
quelle
Ich habe eine Schaltfläche in der Navigationsleiste hinzugefügt und kann auch Berührungsereignisse verarbeiten. Ich möchte dieser Schaltfläche jedoch ein rundes Bild hinzufügen. Können Sie mir mitteilen, wie ich das programmgesteuert tun kann? Können Sie mir auch mitteilen, wie ich die Eigenschaft button programmgesteuert auf "benutzerdefiniert" setzen kann?
ebaccount
Schauen Sie sich die Dokumente für UIButton an. Sie müssen Hintergrundbilder für einen Steuerungsstatus festlegen. Sie möchten unterschiedliche Bilder für Normal und Ausgewählt / Hervorgehoben. Ich glaube, Sie haben den Schaltflächenstil auf UIButtonStyleCustom festgelegt. Sehen Sie sich erneut die Dokumente für die Stileigenschaft in UIButton an.
Kendall Helmstetter Gelner
1
Ist das Hinzufügen eines UIButton über der UIImageView nicht etwas übertrieben? Sie fügen ein zusätzliches Objekt hinzu, während Sie einfach die Berührungsmethoden des bereits vorhandenen UIImageView-Objekts implementieren können. Nein?
Samvermette
32
Wenn Sie sich die Größe eines UIButton im Speicher ansehen, ist dies praktisch nichts und Sie haben nur wenige pro Bildschirm. Was Sie kostenlos erhalten, ist die gesamte Zielaktionsverkabelung für verschiedene Zustände (wie das Ausbessern im Inneren) und auch ein nettes Verhalten wie das Nicht-Auslösen, wenn Sie nach unten drücken, sondern einen Finger zur Seite schieben. Grundsätzlich sind Schaltflächen eines der feinsten Objekte im gesamten System, und zu glauben, dass Sie einen benutzerdefinierten Touch-Code erstellen, der besser funktioniert, ist Wahnsinn. Verwenden Sie das, was billig ist und gut funktioniert, und speichern Sie die benutzerdefinierte Arbeit für Dinge, die die Frameworks noch nicht für Sie erledigen.
Kendall Helmstetter Gelner
6
Sie können ein UIControl auch überlagern, wenn Sie nur Berührungsereignisse benötigen (über addTaget: action: forControlEvents :). Es ist etwas billiger als ein UIButton mit Bildern und mehreren Status. Außerdem verwende ich Präprozessor-Bedingungen, um die Hintergrundfarbe des überlagerten Steuerelements in Pink zu ändern, damit ich genau sehen kann, wo sie sich befinden (und daran denke, dass sie vorhanden sind :-).
Jeff
115

A UIImageViewwird von a abgeleitet, von UIViewdem abgeleitet wird, UIResponderdamit es Berührungsereignisse verarbeiten kann. Hier finden Sie die zur Verfügung stellen möchten touchesBegan, touchesMovedund touchesEndedMethoden und diese aufgerufen werden , wenn der Benutzer das Bild tippt. Wenn Sie nur ein Tap-Ereignis wünschen, ist es einfacher, einfach eine benutzerdefinierte Schaltfläche zu verwenden, bei der das Bild als Schaltflächenbild festgelegt ist. Wenn Sie jedoch eine feinere Kontrolle über Wasserhähne, Bewegungen usw. wünschen, ist dies der richtige Weg.

Sie sollten sich noch ein paar Dinge ansehen:

  • Überschreiben Sie canBecomeFirstResponderund geben Sie JA zurück, um anzuzeigen, dass die Ansicht im Mittelpunkt von Berührungsereignissen stehen kann (die Standardeinstellung ist NEIN).

  • Setzen Sie die userInteractionEnabledEigenschaft auf YES. Der Standardwert für UIViewsist JA, aber für UIImageViewsist NEIN, daher müssen Sie ihn explizit aktivieren .

  • Wenn Sie auf Multitouch-Ereignisse (z. B. Prise, Zoom usw.) reagieren möchten, sollten Sie multipleTouchEnabledauf JA setzen.

Ramin
quelle
Ich habe es versucht, aber trotzdem erhalte ich keine BerührungenBegan-Ereignisse ... warum ist das so?
Markus
5
@ Markus: Ich hatte das gleiche Problem, habe es aber behoben, indem userInteractionEnabledich in meiner übergeordneten Ansicht auf JA gesetzt habe. Siehe stackoverflow.com/questions/5887305/…
Saxon Druce
51

Um einem UIImageView ein Touch-Ereignis hinzuzufügen, verwenden Sie Folgendes in Ihrer .m

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

[myImageView setUserInteractionEnabled:YES];

[myImageView addGestureRecognizer:newTap];


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

hoffentlich hilft das.

Jep.
quelle
userInteractionEnabled = true ist der Teil, der leicht zu vergessen ist, danke.
Michael Peterson
23

Sie können auch einen UIGestureRecognizer hinzufügen. Es ist nicht erforderlich, dass Sie ein zusätzliches Element in Ihre Ansichtshierarchie einfügen, bietet Ihnen jedoch den gesamten gut geschriebenen Code für die Behandlung von Berührungsereignissen mit einer relativ einfachen Oberfläche:

    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
quelle
10
Vergessen Sie nicht, UserInteractionEnabled für imgView_
Anonymous White
13

Ich war in den letzten Stunden in verschiedenen Threads und habe erfolglos versucht, eine Lösung für mein Problem zu finden. Ich sehe, dass viele Entwickler dieses Problem teilen, und ich denke, die Leute hier wissen davon. Ich habe mehrere Bilder in einem UIScrollViewund versuche, Tap-Ereignisse darauf abzurufen.

UIImangeViewIch bekomme keine Ereignisse von einem , aber ich bekomme ein Ereignis von einem ähnlichen UILablemit sehr ähnlichen Parametern, die ich darauf einstelle. unter IOS 5.1.

Ich habe bereits folgendes getan:

  1. Setzen Sie setUserInteractionEnabled sowohl für UIImageView als auch für die übergeordnete Ansicht auf YES.
  2. setze setMultipleTouchEnabled auf YES für UIImageView.
  3. Versuchte Unterklassen UIImageView, hat keiner geholfen.

Wenn ich unten einen Code anhänge, initialisiere ich in diesem Code sowohl a UIImageViewals auch UILabel, und die Beschriftung funktioniert in Bezug auf Auslöseereignisse einwandfrei. Ich habe versucht, irrelevanten Code fernzuhalten. Danke Jungs, 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;

Und die Methode, die das Ereignis behandelt:

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

Wie gesagt, der Etikettentipp wird empfangen.

ilan
quelle
6

Anstatt eine berührbare UIImageView zu erstellen und sie dann in der Navigationsleiste zu platzieren, sollten Sie einfach ein UIBarButtonItem erstellen, das Sie aus einer UIImageView erstellen.

Machen Sie zuerst die Bildansicht:

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

Machen Sie dann das Barbutton-Element aus Ihrer Bildansicht:

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

Fügen Sie dann das Element der Balkentaste zu Ihrer Navigationsleiste hinzu:

self.navigationItem.rightBarButtonItem = yourBarButtonItem;

Denken Sie daran, dass dieser Code in den View Controller eingeht, der sich in einem Viewcontroller-Array des Navigationscontrollers befindet. Im Grunde genommen wird dieses "berührbare Bildschaltflächen-Schaltflächenelement" nur in der Navigationsleiste angezeigt, wenn dieser Ansichts-Controller angezeigt wird. Wenn Sie einen anderen Ansichts-Controller drücken, verschwindet diese Schaltfläche in der Navigationsleiste ~

Yujean
quelle
3

Möglicherweise möchten Sie die touchesBegan:withEvent:Methode der UIView(oder Unterklasse) überschreiben , die Ihre UIImageViewUnteransicht enthält .

Testen Sie bei dieser Methode, ob eine der UITouchBerührungen innerhalb der Grenzen der UIImageViewInstanz liegt (sagen wir, sie wird aufgerufen imageView).

Das heißt, schneidet sich das CGPointElement [touch locationInView]mit dem CGRectElement [imageView bounds]? Schauen Sie sich die Funktion CGRectContainsPointan, um diesen Test auszuführen.

Alex Reynolds
quelle
Danke für deine Antwort. Ich habe die Ansicht folgendermaßen hinzugefügt: [navBar addSubview: self.pImage]; // als Unteransicht der Navigationsleiste hinzugefügt. Ich habe die Funktion überschrieben, aber die Funktion wird nie aufgerufen. Ich habe die Eigenschaft userInteractionEnabled der UIImageView jedoch auf YES gesetzt. Vermisse ich etwas
ebaccount
Schauen Sie sich die Methode touchBegan: withEvent: an. In Suchmaschinen gibt es viele Beispiele dafür, wie dies funktioniert.
Alex Reynolds
1

Zuerst sollten Sie einen UIButton platzieren, dann können Sie entweder ein Hintergrundbild für diese Schaltfläche hinzufügen oder Sie müssen eine UIImageView über der Schaltfläche platzieren.

oder

Sie können die Tippgeste zu einer UIImageView hinzufügen, damit die Klickaktion beim Tippen auf die UIImageView angezeigt wird.

Hilaj
quelle
0

Für diejenigen unter Ihnen, die nach einer Swift 4-Lösung für diese Antwort suchen. Sie können Folgendes verwenden, um ein Berührungsereignis in einer UIImageView zu erkennen.

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

Sie müssen dann Ihren Selektor wie folgt definieren:

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

Fügen Sie dieser Ansicht eine Geste für dieses view.add-Bild hinzu, dann wird auch eine Geste für das Bild erkannt. Könnten Sie es mit der delegierten Methode des Berührungsereignisses versuchen, wird sie in diesem Fall möglicherweise auch erkannt. Vielen Dank

user1240409
quelle