46

Mac OS Xでは、次のようなファーストレスポンダーを見つけることができます。

[[self window] firstResponder]

iOSでそれを行う方法はありますか?isFirstResponderまたは、子コントロールを列挙して、それぞれにメッセージを送信する必要がありますか?

4

4 に答える 4

250

私はVJKのソリューションが本当に好きですが、MattDiPasqualeが示唆しているように、それは必要以上に複雑に思えます。だから私はこのより単純なバージョンを書きました:

Objective-C

UIResponder + FirstResponder.h:

#import <UIKit/UIKit.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

スウィフト4

import UIKit

extension UIResponder {

    private static weak var _currentFirstResponder: UIResponder?

    static var currentFirstResponder: UIResponder? {
        _currentFirstResponder = nil
        UIApplication.shared.sendAction(#selector(UIResponder.findFirstResponder(_:)), to: nil, from: nil, for: nil)

        return _currentFirstResponder
    }

    @objc func findFirstResponder(_ sender: Any) {
        UIResponder._currentFirstResponder = self
    }
}

それがより理にかなっているように思われたので、私もそれをクラスメソッドにしました。これで、次のようなファーストレスポンダーを見つけることができます。[UIResponder currentFirstResponder]


于 2013-01-03T08:40:31.877 に答える
26

UIResponder私はファーストレスポンダーを見つけるためにカテゴリを書きました

@interface UIResponder (firstResponder)
- (id) currentFirstResponder;
@end

#import <objc/runtime.h>
#import "UIResponder+firstResponder.h"

static char const * const aKey = "first";

@implementation UIResponder (firstResponder)

- (id) currentFirstResponder {
    [[UIApplication sharedApplication] sendAction:@selector(findFirstResponder:) to:nil from:self forEvent:nil];
    id obj = objc_getAssociatedObject (self, aKey);
    objc_setAssociatedObject (self, aKey, nil, OBJC_ASSOCIATION_ASSIGN);
    return obj;
}

- (void) setCurrentFirstResponder:(id) aResponder {
    objc_setAssociatedObject (self, aKey, aResponder, OBJC_ASSOCIATION_ASSIGN);
}

- (void) findFirstResponder:(id) sender {
    [sender setCurrentFirstResponder:self];
}

@end

次に、から派生したクラスでは、UIResponderを呼び出すことでファーストレスポンダーを取得できます

UIResponder* aFirstResponder = [self currentFirstResponder];

ただし、最初にUIResponderカテゴリインターフェイスファイルをインポートすることを忘れないでください。

これは文書化されたAPIを使用するため、アプリストアの拒否の問題は発生しません。

于 2012-04-27T21:30:50.657 に答える
12

ステータスを辞任するように依頼できるようにするためだけにファーストレスポンダーが必要な場合は、次の方法で辞任することができます。UIViewには、すべてのUIViewsサブビューを反復処理し、最初の応答者であるすべてのサブビューに辞任を求めるメソッドがあります。

[[self view] endEditing:YES];

AppleのUIViewドキュメントへのリンクは次のとおりです 。「このメソッドは、現在のビューと、現在ファーストレスポンダーであるテキストフィールドのサブビュー階層を調べます。見つかった場合は、そのテキストフィールドにファーストレスポンダーとして辞任するように求めます。パラメータがYESに設定されている場合、テキストフィールドは要求されることさえなく、強制的に辞任されます。」

于 2012-04-25T23:45:33.720 に答える
12

すべての子コントロールを繰り返し処理し、isFirstResponderプロパティをテストする必要があります。に遭遇したらTRUE、ループから抜け出します。

UIView *firstResponder;
for (UIView *view in self.view.subviews) //: caused error
{
    if (view.isFirstResponder)
    {
        firstResponder = view;
        break;
    }
}

より良いソリューション

ヤコブの答えを参照してください。

于 2011-02-17T13:19:13.873 に答える