Mac OS Xでは、次のようなファーストレスポンダーを見つけることができます。
[[self window] firstResponder]
iOSでそれを行う方法はありますか?isFirstResponder
または、子コントロールを列挙して、それぞれにメッセージを送信する必要がありますか?
Mac OS Xでは、次のようなファーストレスポンダーを見つけることができます。
[[self window] firstResponder]
iOSでそれを行う方法はありますか?isFirstResponder
または、子コントロールを列挙して、それぞれにメッセージを送信する必要がありますか?
私はVJKのソリューションが本当に好きですが、MattDiPasqualeが示唆しているように、それは必要以上に複雑に思えます。だから私はこのより単純なバージョンを書きました:
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
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]
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を使用するため、アプリストアの拒否の問題は発生しません。
ステータスを辞任するように依頼できるようにするためだけにファーストレスポンダーが必要な場合は、次の方法で辞任することができます。UIViewには、すべてのUIViewsサブビューを反復処理し、最初の応答者であるすべてのサブビューに辞任を求めるメソッドがあります。
[[self view] endEditing:YES];
AppleのUIViewドキュメントへのリンクは次のとおりです 。「このメソッドは、現在のビューと、現在ファーストレスポンダーであるテキストフィールドのサブビュー階層を調べます。見つかった場合は、そのテキストフィールドにファーストレスポンダーとして辞任するように求めます。パラメータがYESに設定されている場合、テキストフィールドは要求されることさえなく、強制的に辞任されます。」
すべての子コントロールを繰り返し処理し、isFirstResponder
プロパティをテストする必要があります。に遭遇したらTRUE
、ループから抜け出します。
UIView *firstResponder;
for (UIView *view in self.view.subviews) //: caused error
{
if (view.isFirstResponder)
{
firstResponder = view;
break;
}
}
より良いソリューション
ヤコブの答えを参照してください。