プライベートAPIを使用せずに現在のファーストレスポンダーを取得する


339

1か月以上前にアプリを送信し、本日、恐ろしい拒否メールを受け取りました。非公開のAPIを使用しているため、アプリを承認できないことがわかります。具体的には、

アプリケーションに含まれている非公開APIはfirstResponderです。

今、問題のAPI呼び出しは実際に私がSOで見つけた解決策です:

UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
UIView   *firstResponder = [keyWindow performSelector:@selector(firstResponder)];

現在のファーストレスポンダーを画面に表示するにはどうすればよいですか?アプリが拒否されない方法を探しています。


5
むしろビューを反復処理するよりも、あなたはこれを使用することができ、本当に輝かしい:魔法のビットstackoverflow.com/a/14135456/746890
クリス・ノレット

回答:


337

私のアプリケーションの1つでは、ユーザーが背景をタップした場合に、最初のレスポンダーに辞任してもらいたいことがよくあります。この目的のために、UIWindowで呼び出すUIViewにカテゴリを記述しました。

以下はそれに基づいており、最初のレスポンダを返す必要があります。

@implementation UIView (FindFirstResponder)
- (id)findFirstResponder
{
    if (self.isFirstResponder) {
        return self;        
    }
    for (UIView *subView in self.subviews) {
        id responder = [subView findFirstResponder];
        if (responder) return responder;
    }
    return nil;
}
@end

iOS 7以降

- (id)findFirstResponder
{
    if (self.isFirstResponder) {
        return self;
    }
    for (UIView *subView in self.view.subviews) {
        if ([subView isFirstResponder]) {
            return subView;
        }
    }
    return nil;
}

迅速:

extension UIView {
    var firstResponder: UIView? {
        guard !isFirstResponder else { return self }

        for subview in subviews {
            if let firstResponder = subview.firstResponder {
                return firstResponder
            }
        }

        return nil
    }
}

Swiftでの使用例:

if let firstResponder = view.window?.firstResponder {
    // do something with `firstResponder`
}

278
なぜこれは単に呼び出すよりも優れた解決策[self.view endEditing:YES]ですか?
Tim Sullivan、

69
@ティム私はあなたがそれをすることができなかった。これは明らかに、最初のレスポンダを辞任するためのはるかに簡単な方法です。ただし、最初の応答者を特定するための元の質問には役立ちません。
トーマス・ミュラー

17
あなたはそれを辞任よりも、最初の応答者との何かをしたいと思うかもしれないので、また、これは、より良い答えは...ある
エリックB

3
これは、UIViewsのみを検出し、最初のレスポンダーにもなり得る他のUIResponder(UIViewControllerやUIApplicationなど)は検出しないことに注意してください。
Patrick Pijnappel 14

10
iOS 7の違いは何ですか?その場合は、再帰も実行しませんか?
Peter DeWeese 14

531

あなたの最終的な目的が最初のレスポンダーを辞任することだけである場合、これはうまくいくはずです: [self.view endEditing:YES]


122
これが「質問」の答えだと言っている皆さん、実際の質問を見ていただけませんか?現在のファーストレスポンダーを取得する方法を質問します。ファーストレスポンダーを辞任する方法ではありません。
ジャスティンクレディブル2012年

2
そして、このself.view endEditingをどこに呼び出せばよいでしょうか?
user4951

8
これは質問に正確に答えているわけではありませんが、非常に有用な答えであることは明らかです。ありがとう!
NovaJoe

6
質問に対する回答でなくても+1します。どうして?多くの人がこの回答が答えるという質問を心に留めてここに来るので:)少なくとも267人(現時点では)
Rok Jarc

1
これは質問に対する答えではありません。
Sasho 2014年

186

ファーストレスポンダを操作する一般的な方法は、nilターゲットアクションを使用することです。これは、任意のメッセージをレスポンダーチェーン(最初のレスポンダーから開始)に送信し、誰かがメッセージに応答するまで(セレクターと一致するメソッドが実装されているまで)チェーンを下っていく方法です。

キーボードを非表示にする場合、これは最初のレスポンダーであるウィンドウまたはビューに関係なく機能する最も効果的な方法です。

[[UIApplication sharedApplication] sendAction:@selector(resignFirstResponder) to:nil from:nil forEvent:nil];

これはさらに効果的です[self.view.window endEditing:YES]

(コンセプトを思い出させてくれたBigZaphodに感謝)


4
これはとてもクールです。おそらく、私がSOで今まで見た中で最も最近のCocoa Touchトリック。私に終わりがありませんでした!
mluisbrown 2013年

これは100万人のおかげで、FARによる最良のソリューションです。これは、上記の解決策よりもはるかに優れています。アクティブなテキストフィールドがキーボードのアクセサリビューの一部であっても機能するためです(その場合、ビュー階層の一部ではありません)
Pizzaiola Gorgonzola

2
このソリューションはベストプラクティスのソリューションです。システムは最初のレスポンダーが誰であるかをすでに知っているので、それを見つける必要はありません。
2014年

2
この回答には複数の賛成票を投じたいと思います。これは驚異的な天才です。
Reid Main、

1
devios1:Jakobの答えはまさに質問が要求するものですが、それはレスポンダーシステムを設計された方法で使用するのではなく、レスポンダーシステムの上にあるハックです。これはよりクリーンで、ほとんどの人がこの質問に来る目的を達成し、ワンライナーでも達成します。(もちろん、resignFirstResponderだけでなく、ターゲットアクションスタイルのメッセージを送信することもできます)。
nevyn 2017年

98

を呼び出すことで、最初のレスポンダをすばやく見つけることができるカテゴリがあります[UIResponder currentFirstResponder]。次の2つのファイルをプロジェクトに追加するだけです。

UIResponder + FirstResponder.h

#import <Cocoa/Cocoa.h>
@interface UIResponder (FirstResponder)
    +(id)currentFirstResponder;
@end

UIResponder + FirstResponder.m

#import "UIResponder+FirstResponder.h"
static __weak id currentFirstResponder;
@implementation UIResponder (FirstResponder)
    +(id)currentFirstResponder {
         currentFirstResponder = nil;
         [[UIApplication sharedApplication] sendAction:@selector(findFirstResponder:) to:nil from:nil forEvent:nil];
         return currentFirstResponder;
    }
    -(void)findFirstResponder:(id)sender {
        currentFirstResponder = self;
    }
@end

ここでのトリックは、アクションをnilに送信すると、最初のレスポンダに送信されることです。

(私は最初にこの回答をここに公開しました:https : //stackoverflow.com/a/14135456/322427


1
+1これは、これまでに見た問題(および実際の質問)に対する最もエレガントな解決策です。再利用可能で効率的です!この回答に投票してください!
devios1 2014年

3
ブラボー。これは、私がこれまでにObjcで見た中で最も美しくクリーンなハックになるかもしれません...
Aviel Gross

非常に素晴らしい。送信された場合、チェーン内の(もしあれば)誰が特定のアクションメソッドを処理するかを最初のレスポンダに尋ねることができれば、本当にうまくいくはずです。これを使用して、処理できるかどうかに基づいてコントロールを有効または無効にできます。私はこれについて自分の質問に答え、あなたの答えを参照します。
Benjohn


警告:複数のウィンドウを追加し始めた場合、これは機能しません。残念ながら、それ以上の原因を指摘することはできません。
ヒースボーダーズ2017年

41

Jakob Eggerの最も優れた答えに基づいてSwiftに実装された拡張機能を次に示します。

import UIKit

extension UIResponder {
    // Swift 1.2 finally supports static vars!. If you use 1.1 see: 
    // http://stackoverflow.com/a/24924535/385979
    private weak static var _currentFirstResponder: UIResponder? = nil

    public class func currentFirstResponder() -> UIResponder? {
        UIResponder._currentFirstResponder = nil
        UIApplication.sharedApplication().sendAction("findFirstResponder:", to: nil, from: nil, forEvent: nil)
        return UIResponder._currentFirstResponder
    }

    internal func findFirstResponder(sender: AnyObject) {
        UIResponder._currentFirstResponder = self
    }
}

スウィフト4

import UIKit    

extension UIResponder {
    private weak static var _currentFirstResponder: UIResponder? = nil

    public static var current: UIResponder? {
        UIResponder._currentFirstResponder = nil
        UIApplication.shared.sendAction(#selector(findFirstResponder(sender:)), to: nil, from: nil, for: nil)
        return UIResponder._currentFirstResponder
    }

    @objc internal func findFirstResponder(sender: AnyObject) {
        UIResponder._currentFirstResponder = self
    }
}

1
static varがサポートされているswift1.2に対する回答を変更しました。
nacho4d 2015年

こんにちは。viewDidAppear()の新しいシングルビューアプリケーションでこの結果を出力すると、nilになります。ビューが最初のレスポンダーではありませんか?
farhadf 2015年

@LinusGeffarth current代わりに静的メソッドを呼び出す方が理にかなっていますfirstか?
コードコマンダー

そうだと思う、それを編集しました。変数名を省略すると重要な部分が抜けてしまったようです。
LinusGeffarth 2018

29

それはきれいではありませんが、レスポンダーが何であるかわからないときにfirstResponderを辞任する方法:

IBで、またはプログラムで、UITextFieldを作成します。非表示にします。IBで作成した場合は、コードにリンクします。

次に、キーボードを非表示にする場合は、レスポンダを非表示のテキストフィールドに切り替え、すぐに再署名します。

    [self.invisibleField becomeFirstResponder];
    [self.invisibleField resignFirstResponder];

61
これは恐ろしいと同時に天才でもあります。いいね。
Alex Wayne

4
私は少し危険だと思います-Appleは、非表示のコントロールを最初のレスポンダーにすることは意図された動作ではないと判断し、iOSがこれを行わないように「修正」すると、トリックが機能しなくなる可能性があります。
Thomas Tempelmann、2012年

2
または、firstResponderを現在表示されているUITextFieldに割り当て、その特定のtextFieldでresignFirstResponderを呼び出すこともできます。これにより、非表示のビューを作成する必要がなくなります。すべて同じ、+ 1。
Swifty McSwifterton 2013年

3
むしろ恐ろしいだけだと思います...キーボードのレイアウト(または入力ビュー)を非表示にする前に変更する可能性があります
Daniel

19

ネヴィンの答えのSwift 3&4バージョンの場合

UIApplication.shared.sendAction(#selector(UIView.resignFirstResponder), to: nil, from: nil, for: nil)

10

以下は、正しい最初のレスポンダーを報告するソリューションです(他の多くのソリューションはUIViewController最初のレスポンダーとしてa を報告しません)、ビュー階層をループする必要がなく、プライベートAPIを使用しません。

AppleのメソッドsendAction:to:from:forEvent:を利用しています。これは、最初のレスポンダにアクセスする方法をすでに知っています。

2つの方法で調整する必要があります。

  • UIResponder最初のレスポンダで独自のコードを実行できるように拡張します。
  • UIEvent最初のレスポンダを返すためのサブクラス。

これがコードです:

@interface ABCFirstResponderEvent : UIEvent
@property (nonatomic, strong) UIResponder *firstResponder;
@end

@implementation ABCFirstResponderEvent
@end

@implementation UIResponder (ABCFirstResponder)
- (void)abc_findFirstResponder:(id)sender event:(ABCFirstResponderEvent *)event {
    event.firstResponder = self;
}
@end

@implementation ViewController

+ (UIResponder *)firstResponder {
    ABCFirstResponderEvent *event = [ABCFirstResponderEvent new];
    [[UIApplication sharedApplication] sendAction:@selector(abc_findFirstResponder:event:) to:nil from:nil forEvent:event];
    return event.firstResponder;
}

@end

7

ファーストレスポンダは、UIResponderクラスの任意のインスタンスにすることができるため、UIViewsに関係なく、ファーストレスポンダになる可能性のある他のクラスがあります。たとえばUIViewController、最初のレスポンダーかもしれません。

、この主旨あなたは、アプリケーションのウィンドウのrootViewControllerから始まるコントローラの階層をループで最初のレスポンダを取得するための再帰的な方法を見つけるだろう。

あなたはそれから最初のレスポンダーを取得することができます

- (void)foo
{
    // Get the first responder
    id firstResponder = [UIResponder firstResponder];

    // Do whatever you want
    [firstResponder resignFirstResponder];      
}

ただし、最初のレスポンダーがUIViewまたはUIViewControllerのサブクラスでない場合、このアプローチは失敗します。

この問題を解決するには、カテゴリを作成して別の方法UIResponderを実行し、マジックスウィズリングを実行して、このクラスのすべての生きているインスタンスの配列を構築できます。次に、最初のレスポンダを取得するために、単純に反復して各オブジェクトにifと尋ねます-isFirstResponder

このアプローチは、この他の要点に実装されていることがわかります。

それが役に立てば幸い。


7

Swift特定のUIViewオブジェクトを使用すると、これが役立ちます。

func findFirstResponder(inView view: UIView) -> UIView? {
    for subView in view.subviews as! [UIView] {
        if subView.isFirstResponder() {
            return subView
        }

        if let recursiveSubView = self.findFirstResponder(inView: subView) {
            return recursiveSubView
        }
    }

    return nil
}

それをあなたの中に置いてUIViewController、このように使ってください:

let firstResponder = self.findFirstResponder(inView: self.view)

結果はオプション値であるため、指定されたビューのサブビューでfirstResponserが見つからなかった場合はnilになることに注意してください。


5

最初のレスポンダーとなる可能性のあるビューを反復処理し、現在のビュー- (BOOL)isFirstResponderかどうかを判断するために使用します。


4

Peter Steinberger がプライベート通知についてツイートしましたUIWindowFirstResponderDidChangeNotification。これは、firstResponderの変更を監視する場合に確認できます。


プライベートAPIを使用すること、おそらくプライベート通知を使用することも悪い考えかもしれないため、彼は拒否されます...
Laszlo

4

ユーザーが背景領域をタップしたときにキーボードを強制終了する必要がある場合は、ジェスチャー認識機能を追加し、それを使用して[[self view] endEditing:YES]メッセージを送信しませんか?

タップジェスチャ認識機能をxibまたはストーリーボードファイルに追加して、アクションに接続できます。

このように見えて終了

- (IBAction)displayGestureForTapRecognizer:(UITapGestureRecognizer *)recognizer{
     [[self view] endEditing:YES];
}

これは私にとってはうまくいきました。Xibのビューへの接続を1つ選択しました。ReferencingOutlet Collections
James Perih

4

ちょうどそれがここにあるのは素晴らしいJakob EggerのアプローチのSwiftバージョンです:

import UIKit

private weak var currentFirstResponder: UIResponder?

extension UIResponder {

    static func firstResponder() -> UIResponder? {
        currentFirstResponder = nil
        UIApplication.sharedApplication().sendAction(#selector(self.findFirstResponder(_:)), to: nil, from: nil, forEvent: nil)
        return currentFirstResponder
    }

    func findFirstResponder(sender: AnyObject) {
        currentFirstResponder = self
    }

}

3

これは、ユーザーがModalViewControllerで[保存/キャンセル]をクリックしたときに、firstResponderであるUITextFieldを見つけるために行ったものです。

    NSArray *subviews = [self.tableView subviews];

for (id cell in subviews ) 
{
    if ([cell isKindOfClass:[UITableViewCell class]]) 
    {
        UITableViewCell *aCell = cell;
        NSArray *cellContentViews = [[aCell contentView] subviews];
        for (id textField in cellContentViews) 
        {
            if ([textField isKindOfClass:[UITextField class]]) 
            {
                UITextField *theTextField = textField;
                if ([theTextField isFirstResponder]) {
                    [theTextField resignFirstResponder];
                }

            }
        }

    }

}

2

これは私のUIViewControllerカテゴリにあるものです。ファーストレスポンダーの取得など、多くのことに役立ちます。ブロックは素晴らしいです!

- (UIView*) enumerateAllSubviewsOf: (UIView*) aView UsingBlock: (BOOL (^)( UIView* aView )) aBlock {

 for ( UIView* aSubView in aView.subviews ) {
  if( aBlock( aSubView )) {
   return aSubView;
  } else if( ! [ aSubView isKindOfClass: [ UIControl class ]] ){
   UIView* result = [ self enumerateAllSubviewsOf: aSubView UsingBlock: aBlock ];

   if( result != nil ) {
    return result;
   }
  }
 }    

 return nil;
}

- (UIView*) enumerateAllSubviewsUsingBlock: (BOOL (^)( UIView* aView )) aBlock {
 return [ self enumerateAllSubviewsOf: self.view UsingBlock: aBlock ];
}

- (UIView*) findFirstResponder {
 return [ self enumerateAllSubviewsUsingBlock:^BOOL(UIView *aView) {
  if( [ aView isFirstResponder ] ) {
   return YES;
  }

  return NO;
 }];
}


2

次のUIView拡張機能を選択して取得できます(Danielによるクレジット)

extension UIView {
    var firstResponder: UIView? {
        guard !isFirstResponder else { return self }
        return subviews.first(where: {$0.firstResponder != nil })
    }
}

1

あなたもこのように試すことができます:

- (void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event { 

    for (id textField in self.view.subviews) {

        if ([textField isKindOfClass:[UITextField class]] && [textField isFirstResponder]) {
            [textField resignFirstResponder];
        }
    }
} 

私はそれを試しませんでしたが、それは良い解決策のようです


1

romeo https://stackoverflow.com/a/2799675/661022の解決策はすばらしいですが、コードにはもう1つのループが必要であることに気付きました。私はtableViewControllerを使用していました。スクリプトを編集して確認しました。すべてが完璧に機能しました。

私はこれを試すことを勧めました:

- (void)findFirstResponder
{
    NSArray *subviews = [self.tableView subviews];
    for (id subv in subviews )
    {
        for (id cell in [subv subviews] ) {
            if ([cell isKindOfClass:[UITableViewCell class]])
            {
                UITableViewCell *aCell = cell;
                NSArray *cellContentViews = [[aCell contentView] subviews];
                for (id textField in cellContentViews)
                {
                    if ([textField isKindOfClass:[UITextField class]])
                    {
                        UITextField *theTextField = textField;
                        if ([theTextField isFirstResponder]) {
                            NSLog(@"current textField: %@", theTextField);
                            NSLog(@"current textFields's superview: %@", [theTextField superview]);
                        }
                    }
                }
            }
        }
    }
}

ありがとう!正解です。ここに提示されているほとんどの回答は、uitableviewを使用する場合の解決策ではありません。コードを大幅に簡略化し、if if ([textField isKindOfClass:[UITextField class]])を削除してuitextviewを使用できるようにし、firstresponderを返すことができます。
Frade、2015

1

これは再帰の良い候補です!UIViewにカテゴリを追加する必要はありません。

使用法(View Controllerから):

UIView *firstResponder = [self findFirstResponder:[self view]];

コード:

// This is a recursive function
- (UIView *)findFirstResponder:(UIView *)view {

    if ([view isFirstResponder]) return view; // Base case

    for (UIView *subView in [view subviews]) {
        if ([self findFirstResponder:subView]) return subView; // Recursion
    }
    return nil;
}

1

あなたはこのようにプライベートAPIを呼び出すことができます、アップル無視:

UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
SEL sel = NSSelectorFromString(@"firstResponder");
UIView   *firstResponder = [keyWindow performSelector:sel];

1
しかし... 'respondsToSelector'を使用して確認してください
ibcker

私は今 'respondsToSelector'をチェックしますが、それでも警告が表示されます。これは安全ではない可能性があります。どういうわけか警告を取り除くことができますか?
2015

1

@thomas-müllerの応答のSwiftバージョン

extension UIView {

    func firstResponder() -> UIView? {
        if self.isFirstResponder() {
            return self
        }

        for subview in self.subviews {
            if let firstResponder = subview.firstResponder() {
                return firstResponder
            }
        }

        return nil
    }

}

1

私はここでのほとんどとは少し異なるアプローチをとっています。isFirstResponder設定したビューを探すビューのコレクションを反復処理するのではなく、私もメッセージをnilに送信しますが、受信者(存在する場合)を格納し、その値を返して呼び出し元が実際のインスタンスを取得します(存在する場合)。 。

import UIKit

private var _foundFirstResponder: UIResponder? = nil

extension UIResponder{

    static var first:UIResponder?{

        // Sending an action to 'nil' implicitly sends it to the
        // first responder, where we simply capture it for return
        UIApplication.shared.sendAction(#selector(UIResponder.storeFirstResponder(_:)), to: nil, from: nil, for: nil)

        // The following 'defer' statement executes after the return
        // While I could use a weak ref and eliminate this, I prefer a
        // hard ref which I explicitly clear as it's better for race conditions
        defer {
            _foundFirstResponder = nil
        }

        return _foundFirstResponder
    }

    @objc func storeFirstResponder(_ sender: AnyObject) {
        _foundFirstResponder = self
    }
}

次に、これを行うことで、ファーストレスポンダを辞任できます(ある場合)。

return UIResponder.first?.resignFirstResponder()

でも、これもできるようになりました...

if let firstResponderTextField = UIResponder?.first as? UITextField {
    // bla
}

1

UIViewの任意の場所でファーストレスポンダーを見つけるための実装を紹介します。私はそれが私の英語に役立つと申し訳ないことを願っています。ありがとう

+ (UIView *) findFirstResponder:(UIView *) _view {

    UIView *retorno;

    for (id subView in _view.subviews) {

        if ([subView isFirstResponder])
        return subView;

        if ([subView isKindOfClass:[UIView class]]) {
            UIView *v = subView;

            if ([v.subviews count] > 0) {
                retorno = [self findFirstResponder:v];
                if ([retorno isFirstResponder]) {
                    return retorno;
                }
            }
        }
    }

    return retorno;
}

0

以下のコードが機能します。

- (id)ht_findFirstResponder
{
    //ignore hit test fail view
    if (self.userInteractionEnabled == NO || self.alpha <= 0.01 || self.hidden == YES) {
        return nil;
    }
    if ([self isKindOfClass:[UIControl class]] && [(UIControl *)self isEnabled] == NO) {
        return nil;
    }

    //ignore bound out screen
    if (CGRectIntersectsRect(self.frame, [UIApplication sharedApplication].keyWindow.bounds) == NO) {
        return nil;
    }

    if ([self isFirstResponder]) {
        return self;
    }

    for (UIView *subView in self.subviews) {
        id result = [subView ht_findFirstResponder];
        if (result) {
            return result;
        }
    }
    return nil;
}   

0

更新:私は間違っていました。確かにUIApplication.shared.sendAction(_:to:from:for:)、このリンクhttp://stackoverflow.com/a/14135456/746890で示されている最初のレスポンダを呼び出すために使用できます。


ここの答えのほとんどは、ビューの階層にない場合、現在の最初のレスポンダを実際に見つけることができません。たとえば、AppDelegateまたはUIViewControllerサブクラス。

ファーストレスポンダオブジェクトがでなくても、確実に検索できる方法がありますUIView

最初に、のnextプロパティを使用して、それの逆のバージョンを実装しましょうUIResponder

extension UIResponder {
    var nextFirstResponder: UIResponder? {
        return isFirstResponder ? self : next?.nextFirstResponder
    }
}

この計算されたプロパティを使用すると、現在の最初のレスポンダを下から上に見つけることができますUIView。たとえば、からviewUIViewControllerビューコントローラは、最初の応答者であれば、それを管理しています誰。

ただし、トップダウンの解決策、varつまり現在のファーストレスポンダーを取得するための単一の解決策が必要です。

まず、ビュー階層について:

extension UIView {
    var previousFirstResponder: UIResponder? {
        return nextFirstResponder ?? subviews.compactMap { $0.previousFirstResponder }.first
    }
}

これは最初のレスポンダを逆方向に検索し、それが見つからなかった場合、サブビューに同じことをするように伝えます(そのサブビューnextは必ずしもそれ自体ではないため)。これにより、を含む任意のビューからそれを見つけることができますUIWindow

そして最後に、これを構築することができます:

extension UIResponder {
    static var first: UIResponder? {
        return UIApplication.shared.windows.compactMap({ $0.previousFirstResponder }).first
    }
}

したがって、最初のレスポンダを取得する場合は、次のように呼び出すことができます。

let firstResponder = UIResponder.first

0

ファーストレスポンダーを見つける最も簡単な方法:

func sendAction(_ action: Selector, to target: Any?, from sender: Any?, for event: UIEvent?) -> Bool

デフォルトの実装では、アクションメソッドを特定のターゲットオブジェクトにディスパッチします。ターゲットが指定されていない場合は、最初のレスポンダにディスパッチします。

次のステップ:

extension UIResponder
{
    private weak static var first: UIResponder? = nil

    @objc
    private func firstResponderWhereYouAre(sender: AnyObject)
    {
        UIResponder.first = self
    }

    static var actualFirst: UIResponder?
    {
        UIApplication.shared.sendAction(#selector(findFirstResponder(sender:)), to: nil, from: nil, for: nil)
        return UIResponder.first
    }
}

使用法:UIResponder.actualFirst自分の目的のためだけに入手してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.