我在一个多星期前提交了应用,今天收到了可怕的拒绝邮件。它告诉我,我的应用程序不能被接受,因为我使用的是非公共API;具体来说,它说,

应用程序中包含的非公共API是firstResponder。

现在,违规的API调用实际上是一个解决方案,我发现这里的SO:

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

如何在屏幕上显示当前的第一响应器?我正在寻找一种不会让我的应用程序被拒绝的方法。


当前回答

我想和你们分享我的实现,在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;
}

其他回答

这不是很漂亮,但是当我不知道responder是什么时,我辞去firstResponder的方式:

创建一个UITextField,无论是在IB或编程。把它隐藏起来。如果你是用IB写的,就把它链接到你的代码上。

然后,当你想要解散键盘时,你将响应器切换到不可见的文本字段,并立即辞职:

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

你可以像这样调用私有API,苹果忽略:

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

遍历可能是第一响应器的视图,并使用- (BOOL)isFirstResponder来确定它们当前是否是。

操作第一响应器的常用方法是使用nil目标操作。这是一种向响应器链发送任意消息的方式(从第一个响应器开始),并沿着链继续向下,直到有人响应消息(已经实现了与选择器匹配的方法)。

对于取消键盘的情况,这是最有效的方法,无论哪个窗口或视图是第一响应器:

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

这应该比[self.view]更有效。窗口endEditing:是的)。

(感谢BigZaphod提醒我这个概念)

Peter Steinberger刚刚发了关于私有通知UIWindowFirstResponderDidChangeNotification的推特,如果你想观察firstResponder的变化,你可以观察。