Aktualizacja: Myliłem się. Rzeczywiście możesz użyć, UIApplication.shared.sendAction(_:to:from:for:)
aby zadzwonić do pierwszego respondenta pokazanego w tym linku: http://stackoverflow.com/a/14135456/746890 .
Większość odpowiedzi tutaj nie może naprawdę znaleźć bieżącego pierwszego odpowiadającego, jeśli nie znajduje się on w hierarchii widoków. Na przykład AppDelegate
lub UIViewController
podklasy.
Istnieje sposób, aby zagwarantować, że go znajdziesz, nawet jeśli pierwszym obiektem odpowiadającym nie jest UIView
.
Najpierw zaimplementuj jego odwróconą wersję, używając next
właściwości UIResponder
:
extension UIResponder {
var nextFirstResponder: UIResponder? {
return isFirstResponder ? self : next?.nextFirstResponder
}
}
Dzięki tej obliczonej właściwości możemy znaleźć bieżącego pierwszego odpowiadającego od dołu do góry, nawet jeśli nie jest UIView
. Na przykład od a view
do tego, UIViewController
kto nim zarządza, jeśli kontroler widoku jest pierwszym odpowiadającym.
Jednak nadal potrzebujemy odgórnej rozdzielczości, pojedynczej, var
aby uzyskać obecną pierwszą odpowiedź.
Najpierw z hierarchią widoków:
extension UIView {
var previousFirstResponder: UIResponder? {
return nextFirstResponder ?? subviews.compactMap { $0.previousFirstResponder }.first
}
}
Spowoduje to wyszukanie pierwszego odpowiadającego wstecz i gdyby nie mógł go znaleźć, powiedziałby swoim podwykonawcom, aby zrobili to samo (ponieważ jego widok podrzędny next
niekoniecznie jest sam). Dzięki temu możemy go znaleźć z dowolnego widoku, w tym UIWindow
.
I wreszcie możemy zbudować to:
extension UIResponder {
static var first: UIResponder? {
return UIApplication.shared.windows.compactMap({ $0.previousFirstResponder }).first
}
}
Więc jeśli chcesz odzyskać pierwszego respondenta, możesz zadzwonić:
let firstResponder = UIResponder.first