wake-up-neo.com

UIView - "Benutzerinteraktion aktiviert" für Eltern und für Kinder "true"

Es scheint, dass userInteractionEnabled = NO in einer übergeordneten Ansicht die Benutzerinteraktion in allen Unteransichten verhindert. Ist das richtig? Gibt es einen Weg, um das zu umgehen?

49
morgancodes

Das ist richtig, wenn userInteractionEnabled in einer übergeordneten Ansicht auf NO gesetzt ist, wird es auf alle Unteransichten angewendet. Wenn Sie einige Unteransichten benötigen, um die Interaktion zu aktivieren, andere jedoch nicht, können Sie Ihre Unteransichten in zwei übergeordnete Ansichten unterteilen: eine mit userInteractionEnabled = YES und die andere NEIN. Setzen Sie dann diese beiden übergeordneten Ansichten in die Hauptansicht.

33
lazycs

Sie können UIView in Unterklassen unterteilen und hitTest: withEvent: überschreiben, um Touch-Ereignisse an eine von Ihnen angegebene Ansicht zu übergeben (_backView):

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    UIView *view = [super hitTest:point withEvent:event];

    if (view == self) {
        view = _backView;
    }

    return view;
}

Wenn das Berührungsereignis von dieser Ansicht behandelt werden soll, wird es an "_backView" übergeben (dies kann ein IBOutlet sein, damit es mit dem Interface Builder festgelegt werden kann). und wenn es von einer untergeordneten Ansicht behandelt werden soll, geben Sie einfach dieses untergeordnete Element zurück (das Ergebnis von [super hitTest:point withEvent:event];)

Diese Lösung ist in Ordnung, solange Sie wissen, an welche Ansicht Sie die Ereignisse übergeben müssen. Außerdem weiß ich nicht, ob es Probleme gibt, da wir eine Ansicht (_backView) zurückgeben, die keine Unteransicht der aktuellen UIView ist !! aber es hat in meinem Fall gut funktioniert.

Eine bessere Lösung könnte die in Deaktivieren von Berührungen im UIView-Hintergrund sein, damit Schaltflächen in unteren Ansichten angeklickt werden können. Dort wird die Verwendung von -pointInside:withEvent: erwähnt. ; Im Vergleich zur vorherigen Lösung ist dies besser, da Sie kein '_backView' angeben müssen, um die Ereignisse zu empfangen (das Ereignis wird einfach an die nächste Ansicht in der Kette übergeben)! Der Nachteil könnte sein, dass wir -pointInside:withEvent: für alle Unteransichten ausführen müssen (der Overhead ist jedoch möglicherweise vernachlässigbar).

15
Ali

Ich bin gerade in eine seltsame Situation geraten. Ich habe eine UIView (nennen Sie diese, V), die einen UIButton als Unteransicht hat. Rufen Sie dieses UIButton auf, Schaltfläche X. Nachfolgend wird die Methode angegeben, die ich für das Ziel/den Auswahlschalter von Schaltfläche X verwende. Selbst darunter ist die Ansicht V. Der Senderparameter ist Schaltfläche X. 

Die Situation, die mich zu einem Problem führt, ist, dass ich, wenn ich eine andere Schaltfläche auf meiner Benutzeroberfläche (in der Navigationsleiste, diese Schaltfläche Y anrufe) und dann sehr schnell die Taste X drücke, die Schaltfläche Y die Ansicht V deaktiviert, ich immer noch die Berührungsereignis an Schaltfläche X gesendet.

- (void) buttonAction: (UIButton *) sender
{
    NSLog(@"superview: %d", sender.superview.userInteractionEnabled);  
    NSLog(@"button itself: %d", sender.userInteractionEnabled);

    // <snip>
}

Hier ist die Ausgabe:

2014-12-19 16: 57: 53.826 MyApp [6161: 960615] Überblick: 0 
2014-12-19 16: 57: 53.826 MyApp [6161: 960615] -Taste selbst: 1

Das heißt, die Tastenaktion wurde ausgeführt, und die Benutzerinteraktion der Schaltfläche war deaktiviert. Und in der Unteransicht war noch Benutzerinteraktion aktiviert !!

Für diejenigen, die der Meinung sind, dass dies künstlich erscheint, auf der Benutzeroberfläche meiner App, die auf einem iPad (mit iOS 8.1.2) ausgeführt wird, ist dies bei meiner Verwendung der App durch Zufall entstanden. Es war nicht etwas, das ich ursprünglich versuchte zu erzeugen.

Gedanken?

Meine derzeitige Problemumgehung ist unten angegeben, aber es scheint wirklich merkwürdig, dass es notwendig ist!

- (void) buttonAction: (id) sender
{
    NSLog(@"superview: %d", sender.superview.userInteractionEnabled);  
    NSLog(@"button itself: %d", sender.userInteractionEnabled);
    if (! self.userInteractionEnabled) return;

    // <snip>
}
2
Chris Prince

Ich habe mir eine seltsame Lösung dafür ausgedacht. Ich hatte eine Kinderansicht in einer tableView-Zelle, die ich anfassen wollte, aber die Eltern sollten nicht ...

Keine der obigen Lösungen hat für mich funktioniert, aber ich habe eine andere Lösung gefunden. Gehen Sie zum Storyboard und fügen Sie der übergeordneten Ansicht einen tapGestureRecognizer hinzu, um die Berührungen der übergeordneten Ansicht zu absorbieren. Problem gelöst!

0
Alfi

Ich mache dies in einer Xib, die meine "Custom Alert Controller" -Ansicht ist.

for (UIView *subview in self.superview.subviews) {

    if (![subview isEqual:self]) {
        subview.userInteractionEnabled = NO;
    }
}
0
NeoGER89