我在一个多星期前提交了应用,今天收到了可怕的拒绝邮件。它告诉我,我的应用程序不能被接受,因为我使用的是非公共API;具体来说,它说,
应用程序中包含的非公共API是firstResponder。
现在,违规的API调用实际上是一个解决方案,我发现这里的SO:
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
UIView *firstResponder = [keyWindow performSelector:@selector(firstResponder)];
如何在屏幕上显示当前的第一响应器?我正在寻找一种不会让我的应用程序被拒绝的方法。
在我的一个应用程序中,如果用户在后台点击,我经常希望第一响应器辞职。为了这个目的,我在UIView上写了一个category,我在UIWindow上调用它。
下面的代码基于此,应该返回第一个响应器。
@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`
}
使用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)
请注意,结果是一个可选值,所以如果在给定的视图子视图层次结构中没有找到firstResponder,它将为nil。