2010-09-06 16 views
5

Ich habe eine UIView, die eine Reihe von Subviews hat. Die Unteransichten sollten Berührungsereignisse empfangen können, aber aus irgendeinem Grund nimmt die übergeordnete UIView die Berührung und gibt sie nicht weiter. Ich habe es in einem sehr standardgemäß erstellt werden, wie ich immer Ansichten erstellen:iphone/ipad - eltern UIView blockiert Berührungen von Subviews - warum?

UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(0,0,1024,768)]; 
    self.mainView = myView; 
    [myView release]; 

    [self.view addSubview:self.mainView]; 

Dann erstelle ich Subviews und fügen Sie sie als normal:

[self.mainView addSubview:someOtherView]; 

Ich weiß self.mainView wird immer die Touch-Ereignisse, wenn ich höre in der Haupt UIWindow:

VIEW: <UIView: 0x8d34aa0; frame = (0 0; 1024 768); 

Aber warum in der Welt kann ich nicht die Subviews bekommen auf Berührungen erhalten? Ich verstehe nicht, warum das manchmal passiert. Ich ändere keine Standardeigenschaften von mainView.

Antwort

15

Hatte mit dem Rahmen der übergeordneten Ansicht zu tun. Wenn der Rahmen die Unteransichten nicht einschließt, erhalten sie keine Berührungen.

+1

Denken Sie auch daran, bei der Positionierung Ihrer Unteransichten auf dem Bildschirm auf die "Grenzen" Ihrer Elternansicht zu verweisen. Ihr Bild kann die tatsächliche Position auf dem Bildschirm sein oder nicht. – MOK9

+0

@sol: Woher wissen Sie, ob das der Fall ist? – moonman239

0

Berühren Sie die Handler rufen die Superclass-Handler?

z.B. in Ihren BerührungenBegan, rufen:

[super touchesBegan:touches withEvent:event]; 
+0

Ich habe keine Touch-Handler. Die Unteransichten reagieren nicht auf Berührungen. Zum Beispiel funktioniert ein GestureRecognizer auf einer der Unteransichten nicht. – sol

12

UIView-Berührungen werden nicht an Teilansichten übergeben, wenn sie außerhalb der Grenzen der Superview liegen, wie in der Lösung erwähnt.

Wenn Sie jedoch möchten, dass diese Unteransichten auf Berührung reagieren, überschreiben Sie hitTest:withEvent: des Superview.

Documentation on Event Delivery

Touch-Ereignisse. Das Fensterobjekt verwendet die Trefferprüfung und die Antwortkette, um die Ansicht zu finden, die das Berührungsereignis empfängt. Beim Hit-Test ruft ein Fenster hitTest auf: withEvent: in der obersten Ansicht der View-Hierarchie; Diese Methode fährt fort, indem sie pointInside rekursiv aufruft: withEvent: für jede Sicht in der Sichthierarchie, die YES zurückgibt, indem sie die Hierarchie herunterfährt, bis sie die Untersicht findet, innerhalb deren Grenzen die Berührung stattfand. Diese Ansicht wird zur Hit-Test-Ansicht.

  1. Erstellen einer Unterklasse von UIView (oder einem anderen UIView Unterklasse).
  2. Override hitTest: withEvent.
  3. Verwenden Sie diese UIView-Unterklasse als Superview, damit Subview auf Berührungen reagieren kann.

Add-Methode unten in der Unterklasse:

(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event 
{ 
    NSEnumerator *reverseE = [self.subviews reverseObjectEnumerator]; 
    UIView *iSubView; 

    while ((iSubView = [reverseE nextObject])) { 

     UIView *viewWasHit = [iSubView hitTest:[self convertPoint:point toView:iSubView] withEvent:event]; 
     if(viewWasHit) { 
      return viewWasHit; 
     } 

    } 
    return [super hitTest:point withEvent:event]; 
} 

Hinweis: umge enumerator seit Subviews verwendet werden, von hinten nach vorne bestellt und wir wollen zuerst die vorderste Ansicht testen.

+0

Das hat für mich funktioniert. Danke für das Posten! – tjg184

Verwandte Themen