Ich habe meine App vor etwas mehr als einer Woche eingereicht und heute die gefürchtete Ablehnungs-E-Mail erhalten. Es sagt mir, dass meine App nicht akzeptiert werden kann, weil ich eine nicht öffentliche API verwende. konkret heißt es:
Die nicht öffentliche API, die in Ihrer Anwendung enthalten ist, ist firstResponder.
Nun ist der beleidigende API-Aufruf tatsächlich eine Lösung, die ich hier auf SO gefunden habe:
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
UIView *firstResponder = [keyWindow performSelector:@selector(firstResponder)];
Wie bekomme ich den aktuellen Ersthelfer auf den Bildschirm? Ich suche nach einer Möglichkeit, meine App nicht abzulehnen.
objective-c
cocoa-touch
first-responder
Justin Kredible
quelle
quelle
Antworten:
In einer meiner Anwendungen möchte ich oft, dass der Ersthelfer zurücktritt, wenn der Benutzer auf den Hintergrund tippt. Zu diesem Zweck habe ich eine Kategorie in UIView geschrieben, die ich im UIWindow aufrufe.
Das Folgende basiert darauf und sollte den Ersthelfer zurückgeben.
iOS 7+
Schnell:
Anwendungsbeispiel in Swift:
quelle
[self.view endEditing:YES]
?Wenn Ihr letztendliches Ziel nur darin besteht, den Ersthelfer zurückzutreten, sollte dies funktionieren:
[self.view endEditing:YES]
quelle
Eine übliche Methode zur Manipulation des Ersthelfers besteht darin, keine gezielten Aktionen auszuführen. Dies ist eine Möglichkeit, eine beliebige Nachricht an die Antwortkette zu senden (beginnend mit dem ersten Antwortenden) und die Kette entlang fortzufahren, bis jemand auf die Nachricht antwortet (hat eine Methode implementiert, die dem Selektor entspricht).
Für den Fall, dass die Tastatur geschlossen wird, ist dies die effektivste Methode, die unabhängig vom Fenster oder der Ansicht als Ersthelfer funktioniert:
Dies sollte effektiver sein als gerade
[self.view.window endEditing:YES]
.(Danke an BigZaphod , der mich an das Konzept erinnert hat)
quelle
Hier ist eine Kategorie, mit der Sie schnell den Ersthelfer finden können, indem Sie anrufen
[UIResponder currentFirstResponder]
. Fügen Sie Ihrem Projekt einfach die folgenden zwei Dateien hinzu:UIResponder + FirstResponder.h
UIResponder + FirstResponder.m
Der Trick dabei ist, dass das Senden einer Aktion an nil sie an den Ersthelfer sendet.
(Ich habe diese Antwort ursprünglich hier veröffentlicht: https://stackoverflow.com/a/14135456/322427 )
quelle
Hier ist eine in Swift implementierte Erweiterung, die auf Jakob Eggers hervorragender Antwort basiert:
Swift 4
quelle
current
anstelle von aufzurufenfirst
?Es ist nicht schön, aber wie ich den ersten Antwortgeber zurücktrete, wenn ich nicht weiß, was der Antwortende ist:
Erstellen Sie ein UITextField, entweder in IB oder programmgesteuert. Mach es versteckt. Verknüpfen Sie es mit Ihrem Code, wenn Sie es in IB gemacht haben.
Wenn Sie dann die Tastatur schließen möchten, schalten Sie den Responder in das unsichtbare Textfeld und geben es sofort auf:
quelle
Für eine Swift 3 & 4-Version von Nevyns Antwort:
quelle
Hier ist eine Lösung, die den richtigen Ersthelfer meldet (viele andere Lösungen melden beispielsweise keinen
UIViewController
als Ersthelfer), keine Schleife über die Ansichtshierarchie erfordert und keine privaten APIs verwendet.Es nutzt Apples Methode sendAction: to: from: forEvent:, die bereits weiß, wie man auf den Ersthelfer zugreift .
Wir müssen es nur auf zwei Arten optimieren:
UIResponder
Sie, damit unser eigener Code auf dem Ersthelfer ausgeführt werden kann.UIEvent
, um den Ersthelfer zurückzugeben.Hier ist der Code:
quelle
Der Ersthelfer kann eine beliebige Instanz der Klasse UIResponder sein, daher gibt es andere Klassen, die trotz der UIViews möglicherweise der Ersthelfer sind. Zum Beispiel
UIViewController
könnte auch der Ersthelfer sein.In dieser Übersicht finden Sie einen rekursiven Weg, um den Ersthelfer zu erhalten, indem Sie die Hierarchie der Controller ausgehend vom rootViewController der Anwendungsfenster durchlaufen.
Sie können dann den Ersthelfer abrufen, indem Sie dies tun
Wenn der Ersthelfer jedoch keine Unterklasse von UIView oder UIViewController ist, schlägt dieser Ansatz fehl.
Um dieses Problem zu beheben, können wir einen anderen Ansatz
UIResponder
wählen, indem wir eine Kategorie erstellen und ein magisches Swizzeling durchführen, um ein Array aller lebenden Instanzen dieser Klasse erstellen zu können. Um den Ersthelfer zu erhalten, können wir einfach iterieren und jedes Objekt fragen, ob-isFirstResponder
.Dieser Ansatz ist in diesem anderen Kern implementiert .
Ich hoffe es hilft.
quelle
Mit Swift und einem bestimmten
UIView
Objekt kann dies helfen:Legen Sie es einfach in Ihre
UIViewController
und verwenden Sie es wie folgt:Beachten Sie, dass das Ergebnis ein optionaler Wert ist, sodass er null ist, falls in den Unteransichten der angegebenen Ansichten kein firstResponser gefunden wurde.
quelle
Durchlaufen Sie die Ansichten, die der Ersthelfer sein könnten, und verwenden Sie sie,
- (BOOL)isFirstResponder
um festzustellen, ob sie aktuell sind.quelle
Peter Steinberger hat gerade über die private Benachrichtigung getwittert
UIWindowFirstResponderDidChangeNotification
, die Sie beobachten können, wenn Sie die Änderung von firstResponder beobachten möchten.quelle
Wenn Sie nur die Tastatur ausschalten müssen, wenn der Benutzer auf einen Hintergrundbereich tippt, fügen Sie einen Gestenerkenner hinzu und senden Sie die
[[self view] endEditing:YES]
Nachricht damit.Sie können den Tap-Gestenerkenner in die xib- oder Storyboard-Datei einfügen und mit einer Aktion verbinden.
sieht so aus dann fertig
quelle
Genau hier ist die Swift-Version des fantastischen Ansatzes von Jakob Egger:
quelle
Folgendes habe ich getan, um herauszufinden, welcher UITextField der erste Antwortende ist, wenn der Benutzer in einem ModalViewController auf Speichern / Abbrechen klickt:
quelle
Dies ist, was ich in meiner UIViewController-Kategorie habe. Nützlich für viele Dinge, einschließlich Ersthelfer. Blöcke sind großartig!
quelle
Wenn eine Kategorie aktiviert ist
UIResponder
, können Sie dasUIApplication
Objekt legal bitten , Ihnen mitzuteilen, wer der Ersthelfer ist.Sieh dir das an:
Gibt es eine Möglichkeit, eine iOS-Ansicht zu fragen, welches ihrer Kinder den Ersthelferstatus hat?
quelle
Sie können die folgende
UIView
Erweiterung auswählen , um sie zu erhalten (Gutschrift von Daniel) :quelle
Sie können es auch so versuchen:
Ich habe es nicht ausprobiert, aber es scheint eine gute Lösung zu sein
quelle
Die Lösung von Romeo https://stackoverflow.com/a/2799675/661022 ist cool, aber ich habe festgestellt, dass der Code eine weitere Schleife benötigt. Ich habe mit tableViewController gearbeitet. Ich habe das Skript bearbeitet und dann überprüft. Alles hat perfekt funktioniert.
Ich habe empfohlen, dies zu versuchen:
quelle
if ([textField isKindOfClass:[UITextField class]])
erheblich vereinfachen, sogar das if entfernen, die Verwendung für uitextview zulassen, und den Erstantwortenden zurückgeben.Dies ist ein guter Kandidat für eine Rekursion! UIView muss keine Kategorie hinzugefügt werden.
Verwendung (von Ihrem View Controller):
Code:
quelle
Sie können privite API wie folgt nennen, Apple ignorieren:
quelle
Schnelle Version von @ thomas-müllers Antwort
quelle
Ich habe einen etwas anderen Ansatz als die meisten hier. Anstatt die Sammlung von Ansichten zu durchlaufen und nach der eingestellten zu suchen
isFirstResponder
, sende ich auch eine Nachricht annil
, speichere aber den Empfänger (falls vorhanden) und gebe diesen Wert zurück, damit der Anrufer die tatsächliche Instanz erhält (erneut, falls vorhanden). .Ich kann dann den Ersthelfer, falls vorhanden, zurücktreten, indem ich dies tue ...
Aber das kann ich jetzt auch ...
quelle
Ich möchte Ihnen meine Implementierung für die Suche nach Ersthelfern in UIView mitteilen. Ich hoffe es hilft und entschuldige mich für mein Englisch. Vielen Dank
quelle
Code unter Arbeit.
quelle
Update: Ich habe mich geirrt. Sie können in der Tat
UIApplication.shared.sendAction(_:to:from:for:)
den in diesem Link gezeigten Ersthelfer anrufen: http://stackoverflow.com/a/14135456/746890 .Die meisten Antworten hier können den aktuellen Ersthelfer nicht wirklich finden, wenn er nicht in der Ansichtshierarchie enthalten ist. Zum Beispiel
AppDelegate
oderUIViewController
Unterklassen.Es gibt eine Möglichkeit, sicherzustellen, dass Sie es finden, auch wenn das Ersthelferobjekt kein a ist
UIView
.Lassen Sie uns zunächst eine umgekehrte Version davon implementieren, indem Sie die
next
Eigenschaft vonUIResponder
:Mit dieser berechneten Eigenschaft können wir den aktuellen Ersthelfer von unten nach oben finden, auch wenn dies nicht der Fall ist
UIView
. Zum Beispiel von aview
nachUIViewController
wer es verwaltet, wenn der View Controller der Ersthelfer ist.Wir benötigen jedoch immer noch eine Top-Down-Auflösung, eine einzige
var
, um den aktuellen Ersthelfer zu erhalten.Zunächst mit der Ansichtshierarchie:
Dadurch wird der Ersthelfer rückwärts gesucht, und wenn er nicht gefunden werden kann, werden seine Unteransichten angewiesen, dasselbe zu tun (da die Unteransichten
next
nicht unbedingt selbst sind). Damit können wir es aus jeder Sicht finden, auchUIWindow
.Und schließlich können wir dies bauen:
Wenn Sie also den Ersthelfer abrufen möchten, können Sie anrufen:
quelle
Einfachster Weg, um einen Ersthelfer zu finden:
Nächster Schritt:
Verwendung: Holen Sie sich einfach
UIResponder.actualFirst
für Ihre eigenen Zwecke.quelle